2019-12-10-本周学习周报

学习周报

Posted by EWL on December 10, 2019

2019-12-10-本周学习周报

学习总览

JavaScript

  • this
  • 闭包
  • apply/call/bind

CSS

  • grid布局之网格容器相关属性

HTTP

  • http协议初探

学习内容

this

闭包

apply/call/bind

grid布局

理解网格布局

网格,就是一系列相交的水平线与垂直线,组成了网格的列与行。当我们想定义某一个元素的位置时,只需要按照一定的规则将元素的位置设置到对应的行和列上即可,就像横坐标和纵坐标结合起来就能确定一个点一样,在网格布局中这种思想依旧适用。

但是,我们会发现这种布局方式看起来似曾相识,很像表格布局,但是表格布局不是已经被淘汰了吗,grid布局相对比table表格布局而言又有什么优势呢?

表格布局的劣势

  • 样板代码繁多冗杂
  • 修改代码相对繁琐
  • 页面刷新很慢,性能很差

grid布局的优势与兼容性

  • 性能较好
  • 固定或弹性的轨道尺寸,属于二维布局(对比flexBox就属于一维布局,以轴线为准)
  • 可以定位容器中的子项目
  • 可以额外创建行列来保存内容
  • 对齐控制灵活
  • 可以控制重叠的内容,调整z轴上的显示优先级(有点类似于z-index属性)

当前grid布局的兼容性已经很好了,具体可以点击查看

grid与flex谁更好呢

  • flex是一维布局,只能在一条直线上做子项目排列,无论是方向还是对齐方式又或者是溢出折行都是一维层面的问题;grid是在横纵两个方向去排列子项目,某种程度上可以保证子项目能位于任何我们想让它在的位置
  • gird并非用来代替flex布局,grid只是比flex高一维度而已,两者结合起来效果更好

grid布局相关概念

  • 网格容器(grid container)
  • 网格项(grid item)
  • 网格线(grid line)
  • 网格轨道(grid track)
  • 网格单元(grid cell)
  • 网格区域(grid area)

网格容器是应用了display: grid的元素,是所有网格项的父元素。

网格项是网格容器的子元素。

网格线组成了网格项的分界线,但是网格线在定义网格容器的时候就已经定义了和网格项没有什么固定的关系。

网格轨道是两个相邻网格线之间的条状区域,可能是横向也可能是纵向,并且轨道的两边(纵向轨道的上下两边/横向轨道的左右两边)一定会紧贴网格容器边缘;前面提到网格线和网格项没有直接关系,而网格线组成的网格轨道自然也和网格项没有直接的关系。

网格单元是有两条相邻的列网格线和两条相邻的行网格线组成的,交叉形成一个矩形区域。(与网格项作对比的话,网格项是实际的DOM元素,而网格单元仅仅是一种概念上的东西,并不能从元素查找中找到实实在在的HTML元素)

网格区域是指任意四条横纵交错的网格线圈起来的一部分空间。

grid新引入单位

  • fr
  • gr

fr指剩余空间分配数,用于在一系列长度值中分配剩余空间,如果容器中已指定了多个部分,则剩余的空间根据各自的数字按比例分配。

gr指网格数,不在标准中。(网格布局还在完善中,没有完全定稿,所以这个单位不推荐在生产环境使用)

网格布局容器相关属性

(1) display: grid/inline-grid/subgrid grid用于生成块级网格容器,inline-grid用于生成行内块级网格容器,subgrid(目前兼容性堪忧,基本都不支持,不推荐使用)表示当前元素如果已经是网格项的话,使用该属性值会继承其父网格容器的行、列大小。

补充:如果容器已经设置了网格布局,那么其网格项的以下几种属性不再生效:

  1. columns
  2. float
  3. clear
  4. vertical-align
  5. 对子项的display设置inline-block/table-cell

(2) template

  • grid-template-columns划分列数
  • grid-template-rows划分行数

上述两个属性的属性值规则:

  • 轨道大小(可以使用css长度单位,px/em等,也可使用百分比,或者分数fr)
  • 网格线名称(任何名称均可)

示例如下:

div {
  display: grid;
  grid-template-columns: 40px 50px auto 50px 40px;
  grid-template-rows: 25% 100px auto;
}

最终形成的效果就是:纵向会形成五列,从左到右宽度依次为40px/50px/(总宽度-其他四列)/50px/40px;横向会形成三行,从上到下高度依次是25%总高度/100px/(总高度-其他两行)

参考demo 同时设置auto与fr单位

(3) gap

  • grid-row-gap 网格项行间距
  • grid-column-gap 网格项列间距

示例如下:

div {
  display: grid;
  width: 300px;
  grid-template-columns: 50px 50px auto;
  grid-template-rows: repeat(4, 50px);
  grid-row-gap: 20px;
  grid-column-gap: 10px;  
}

最终形成的效果如图所示: image.png

(4) items

  • justify-items 设置设置网格项内容的水平排布位置
  • align-items 设置网格项内容的竖直排布位置
  • place-items 同时设置以上两个属性,即简写形式

Tips:此处需要再次强调,网格项和网格单元是不一样的,这里所有的属性值都是作用在网格项身上的,会影响网格项的排布位置

以上justify-items和align-items的可取属性值都是一样,包含的属性值有:start/end/center/stretch

示例如下:

.grid-wrap {
  display: grid;
  width: 300px;
  height: 400px;
  grid-template-columns: 50px 50px auto;
  grid-template-rows: 50px 50px 60px auto 50px;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  // 可取的值:start/end/center/stretch
  justify-items: stretch;
  align-items: center;
  
  .grid-item {
    background: blue;
  }
}

最终形成的效果如图所示: image.png

(5) content

  • justify-content 设置整个内容区域在容器中的水平位置
  • align-content 设置整个内容区域在容器中的竖直位置
  • place-content 同时设置以上两个属性,即简写形式

以上justify-items和align-items的可取属性值都是一样,包含的属性值有:start/end/center/stretch/space-around/space-between/space-evenly

那么什么时候会用到content相关的属性呢?答案就是当所有的网格单元宽度(高度)加起来都没有网格容器的宽度(高度)大,我们就可以使用content相关属性去安排剩余空出来的空间,告诉网格单元在水平方向或者竖直方向应该怎么排列。

示例代码如下:

.grid-wrap {
  display: grid;
  width: 300px;
  height: 400px;
  grid-template-rows: 100px 100px;
  grid-template-columns: 100px 100px;
  grid-row-gap: 10px;
  grid-column-gap: 10px;
  justify-items: center;
  align-items: center;
  justify-content: end;
  align-content: end;
  
  .grid-item {
    background: blue;
    color: #fff;
  }
}

上述代码设置的样式字面意思即横向网格行有两行,单行高度为100px;纵向网格列有两列,单列的宽度为100px;在此基础上又得知网格容器的宽高是300px/400px,这就说明横向会空出来100px,纵向会空出来200px。此时设置justify-content: end;就可以让这四个网格单元构成的网格区域在水平方向上从右向左排列(竖直方向同理),效果如图:

image.png

其他几种属性值的样式,可参考这里:

Tips: stretch属性值的含义是将网格单元的大小拉伸至充满整个网格容器,而提前设置过grid-template-rows或者grid-template-columns的网格容器在设置stretch时是不生效的,这说明grid-template-columns和justify-content是互斥的,同理作用于grid-template-rows与align-content。

(6) grid-auto

  • grid-auto-columns 多余生成的网格列的列宽
  • grid-auto-rows 多余生成的网格行的行高

有时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。如果我们不设置这些多出来的网格轨道的宽高,那么他们会主动去填满剩余的空间,如果要设置他们的宽高就需要依赖上面这两个属性。

示例代码如下:

<div class="grid-wrap">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>

<b>我将grid-auto-row设置为了20px</b>
<div class="grid-wrap grid-auto">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>
.grid-wrap {
  display: grid;
  border: 1px solid red;
  width: 200px;
  height: 200px;
  grid-template-rows: 50px 50px;
  grid-template-columns: 30px 30px;
  grid-row-gap: 10px;
  grid-column-gap: 10px;
  margin-bottom: 36px;
  
  .grid-item {
    background: blue;
  }
  
  &.grid-auto {
    grid-auto-rows: 20px;
  }
}

效果如图所示: image.png

完整demo示例

HTTP协议

TCP/IP协议族以及分层

在了解HTTP之前,需要先了解一下TCP/IP协议族。通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作的。而 HTTP 属于它内部的一个子集。

TCP/IP是互联网相关的各类协议族的总称.png

TCP/IP协议族中很重要的一部分就是分层,依次分为四层:应用层、传输层、网络层、数据链路层。

应用层

HTTP协议就在应用层,该层决定了向用户提供应用服务时通信的活动,同时预存了各类通用的应用服务,例如FTP(文件传输协议)以及DNS服务(域名系统,可以用于域名解析)。

传输层

传输层的上层就是应用层,提供处于网络连接中的两台计算机之间的数据传输。 在传输层还存在两个性质不同的协议:TCP(传输控制协议)以及UDP(用户数据报协议)。

网络层

网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。

与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。

数据链路层

用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。

利用TCP/IP协议族进行网络通信的时候,发送方会从应用层向下走,接收方则会从链路层往上走。简要过程如下图所示:

传输过程层级走向.png

既然HTTP是TCP/IP协议族的子集,那么上面这张图所示的通信方式也适用于HTTP。

基于上面这张图,我们来具体了解一下传输是如何进行的,假设我们想看某一个web页面,那么我们就要向服务端在应用层发起一个HTTP请求,接着传输层(TCP协议)会将从应用层接收到的数据进行分割(体积更小,利于传输),并且打上序号(用于后续进行数据的有序拼合)以及端口号,之后再转发给网络层(IP协议),网络层会增加作为通信目的地的MAC地址之后转发给数据链路层。

简而言之,就是我们的传输内容在前半段传输的每一层都会被该层添加一些内容,每通过一层都会增加一个首部,HTTP首部–>TCP首部–>IP首部–>以太网首部,然后在后半段反层级传递时会逐渐脱去对应的