add files
This commit is contained in:
		
							parent
							
								
									b410477aa9
								
							
						
					
					
						commit
						75fa75139b
					
				
							
								
								
									
										5
									
								
								00-前端工具/VS Code.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								00-前端工具/VS Code.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
问题:
 | 
			
		||||
 | 
			
		||||
解决;You can kill the Microsoft.VSCode.Cpp.IntelliSense.Msvc process to save the file successfully. 也就是 IntelliSense 这个进程。
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
一个盒子中主要的属性就5个:width、height、padding、border、margin。如下:
 | 
			
		||||
 | 
			
		||||
- width和height:内容的宽度、高度(不是盒子的宽度、高度)。
 | 
			
		||||
- width和height:**内容**的宽度、高度(不是盒子的宽度、高度)。
 | 
			
		||||
- padding:内边距。
 | 
			
		||||
- border:边框。
 | 
			
		||||
- margin:外边距。
 | 
			
		||||
@ -38,7 +38,7 @@
 | 
			
		||||
注意:**宽度和真实占有宽度,不是一个概念!**来看下面这例子。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 标准盒子模型和IE盒子模型
 | 
			
		||||
### 标准盒模型和IE盒模型
 | 
			
		||||
 | 
			
		||||
> 我们目前所学习的知识中,以标准盒子模型为准。
 | 
			
		||||
 | 
			
		||||
@ -53,8 +53,20 @@ IE盒子模型:
 | 
			
		||||
上图显示:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 - 在 CSS 盒子模型 (Box Model) 规定了元素处理元素的几种方式:  <font color="#0000FF">**内容、内边距、边框、外边距**</font>。
 | 
			
		||||
 - 在 CSS的<font color="#0000FF">**标准盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域**</font>的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。<font color="#0000FF">**IE盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域+border+padding**</font>的宽度和高度。
 | 
			
		||||
在 CSS 盒子模型 (Box Model) 规定了元素处理元素的几种方式:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- width和height:**内容**的宽度、高度(不是盒子的宽度、高度)。
 | 
			
		||||
- padding:内边距。
 | 
			
		||||
- border:边框。
 | 
			
		||||
- margin:外边距。
 | 
			
		||||
 | 
			
		||||
CSS盒模型和IE盒模型的区别:
 | 
			
		||||
 | 
			
		||||
 - 在 <font color="#0000FF">**标准盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域**</font>的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。
 | 
			
		||||
 | 
			
		||||
 - <font color="#0000FF">**IE盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域+border+padding**</font>的宽度和高度。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 注:Android中也有margin和padding的概念,意思是差不多的,如果你会一点Android,应该比较好理解吧。区别在于,Android中没有border这个东西,而且在Android中,margin并不是控件的一部分,我觉得这样做更合理一些,呵呵。
 | 
			
		||||
<br>
 | 
			
		||||
@ -272,7 +284,6 @@ padding: 20px;
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**题目3**:现在给你一个盒子模型图,请写出代码,试着用最最简单的方法写。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
@ -804,9 +804,11 @@ _zoom:1;
 | 
			
		||||
> 我们来讲一下浮动中和margin相关的知识。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### margin塌陷
 | 
			
		||||
### margin塌陷/margin重叠
 | 
			
		||||
 | 
			
		||||
**标准文档流中,竖直方向的margin不叠加,以较大的为准**(水平方向的margin是可以叠加的,即水平方向没有塌陷现象)。如下图所示:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**标准文档流中,竖直方向的margin不叠加,取**较大的值**作为margin(水平方向的margin是可以叠加的,即水平方向没有塌陷现象)。如下图所示:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -816,6 +818,37 @@ _zoom:1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 善于使用父亲的padding,而不是儿子的margin
 | 
			
		||||
 | 
			
		||||
我们来看一个奇怪的现象。现在有下面这样一个结构:(div中放一个p)
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
	<div>
 | 
			
		||||
		<p></p>
 | 
			
		||||
	</div>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的结构中,我们尝试通过给儿子`p`一个`margin-top:50px;`的属性,让其与父亲保持50px的上边距。结果却看到了下面的奇怪的现象:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
此时我们给父亲div加一个border属性,就正常了:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
如果父亲没有border,那么儿子的margin实际上踹的是“流”,踹的是这“行”。所以,父亲整体也掉下来了。
 | 
			
		||||
 | 
			
		||||
**margin这个属性,本质上描述的是兄弟和兄弟之间的距离; 最好不要用这个marign表达父子之间的距离。**
 | 
			
		||||
 | 
			
		||||
所以,如果要表达父子之间的距离,我们一定要善于使用父亲的padding,而不是儿子的margin。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 盒子居中`margin:0 auto;`
 | 
			
		||||
 | 
			
		||||
margin的值可以为auto,表示自动。当left、right两个方向都是auto的时候,盒子居中了:
 | 
			
		||||
@ -853,6 +886,8 @@ text-align:left;     //没啥用,因为默认居左
 | 
			
		||||
text-align:right;    //文本居右
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 善于使用父亲的padding,而不是儿子的margin
 | 
			
		||||
 | 
			
		||||
我们来看一个奇怪的现象。现在有下面这样一个结构:(div中放一个p)
 | 
			
		||||
 | 
			
		||||
@ -5,14 +5,24 @@
 | 
			
		||||
> 以下是正文。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 绑定事件的两种方式
 | 
			
		||||
## 绑定事件的两种方式/DOM事件的级别
 | 
			
		||||
 | 
			
		||||
我们在上一篇文章 [DOM操作详解](http://www.cnblogs.com/smyhvae/p/8366012.html) 中已经讲过事件的概念。这里讲一下注册事件的两种方式,我们以onclick事件为例。
 | 
			
		||||
 | 
			
		||||
### 方式一:onclick
 | 
			
		||||
### DOM0的写法:onclick
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    element.onclick = function () {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
举例:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<body>
 | 
			
		||||
<button>点我</button>
 | 
			
		||||
@ -41,15 +51,24 @@
 | 
			
		||||
 | 
			
		||||
我们可以看到,这种绑定事件的方式,会层叠掉之前的事件。
 | 
			
		||||
 | 
			
		||||
### 方式二:addEventListener
 | 
			
		||||
### DOM2的写法:addEventListener
 | 
			
		||||
 | 
			
		||||
addEventListener()里的参数:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    element.addEventListener('click', function () {
 | 
			
		||||
 | 
			
		||||
    }, false);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
参数解释:
 | 
			
		||||
 | 
			
		||||
- 参数1:事件名(注意,没有on)
 | 
			
		||||
 | 
			
		||||
- 参数2:事件名(执行函数)
 | 
			
		||||
 | 
			
		||||
- 参数3:事件名(捕获或者冒泡)
 | 
			
		||||
- 参数3:**true表示捕获阶段触发,false表示冒泡阶段触发(默认)**。如果不写,则默认为false。【重要】
 | 
			
		||||
 | 
			
		||||
举例:
 | 
			
		||||
 | 
			
		||||
@ -522,7 +541,7 @@ function scroll() {  // 开始封装自己的scrollTop
 | 
			
		||||
 | 
			
		||||
暂略。
 | 
			
		||||
 | 
			
		||||
## 事件冒泡
 | 
			
		||||
## DOM事件流
 | 
			
		||||
 | 
			
		||||
事件传播的三个阶段是:事件捕获、事件冒泡和目标。
 | 
			
		||||
 | 
			
		||||
@ -539,7 +558,95 @@ function scroll() {  // 开始封装自己的scrollTop
 | 
			
		||||
PS:这个概念类似于 Android 里的 **touch 事件传递**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 事件冒泡的概念
 | 
			
		||||
### 事件捕获
 | 
			
		||||
 | 
			
		||||
addEventListener可以捕获事件:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    box1.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 box3");
 | 
			
		||||
    }, true);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的方法中,参数为true,代表事件在捕获阶段执行。
 | 
			
		||||
 | 
			
		||||
代码演示:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    //参数为true,代表捕获;参数为false或者不写参数,代表冒泡
 | 
			
		||||
    box3.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 child");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    box2.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 father");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    box1.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 grandfather");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 body");
 | 
			
		||||
    }, true);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
效果演示:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
**说明**:捕获阶段,事件依次传递的顺序是:window --> document --> html--> body --> 父元素、子元素、目标元素。
 | 
			
		||||
 | 
			
		||||
PS1:第一个接收到事件的对象是 **window**(有人会说body,有人会说html,这都是错误的)。
 | 
			
		||||
 | 
			
		||||
PS2:JS中涉及到DOM对象时,有两个对象最常用:window、doucument。它们俩也是最先获取到事件的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
事件捕获阶段的完整写法是:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    window.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 window");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 document");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.documentElement.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 html");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.body.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 body");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    fatherBox.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 father");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    childBox.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 child");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**补充一个知识点:**
 | 
			
		||||
 | 
			
		||||
在 js中:
 | 
			
		||||
 | 
			
		||||
- 如果想获取 `html`节点,方法是`document.documentElement`。
 | 
			
		||||
 | 
			
		||||
- 如果想获取 `body` 节点,方法是:`document.body`。
 | 
			
		||||
 | 
			
		||||
二者不要混淆了。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 事件冒泡
 | 
			
		||||
 | 
			
		||||
**事件冒泡**: 当一个元素上的事件被触发的时候(比如说鼠标点击了一个按钮),同样的事件将会在那个元素的所有**祖先元素**中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
 | 
			
		||||
 | 
			
		||||
@ -572,6 +679,8 @@ PS:这个概念类似于 Android 里的 **touch 事件传递**。
 | 
			
		||||
 | 
			
		||||
上图显示,当我点击儿子 box3的时候,它的父亲box2、box1、body都依次被触发了。即使我改变代码的顺序,也不会影响效果的顺序。
 | 
			
		||||
 | 
			
		||||
当然,上面的代码中,我们用 addEventListener 这种 DOM2的写法也是可以的,但是第三个参数要写 false,或者不写。
 | 
			
		||||
 | 
			
		||||
**冒泡顺序**:
 | 
			
		||||
 | 
			
		||||
一般的浏览器: (除IE6.0之外的浏览器)
 | 
			
		||||
@ -582,50 +691,13 @@ IE6.0:
 | 
			
		||||
 | 
			
		||||
- div -> body -> html -> document
 | 
			
		||||
 | 
			
		||||
### 事件捕获
 | 
			
		||||
 | 
			
		||||
addEventListener可以捕获事件:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    box1.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 box3");
 | 
			
		||||
    }, true);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的方法中,参数为true,代表捕获;参数为false或者不写参数,代表冒泡。
 | 
			
		||||
 | 
			
		||||
代码演示:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    //参数为true,代表捕获;参数为false或者不写参数,代表冒泡
 | 
			
		||||
    box3.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 child");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    box2.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 father");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    box1.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 grandfather");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 body");
 | 
			
		||||
    }, true);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
效果演示:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
### 不是所有的事件都能冒泡
 | 
			
		||||
 | 
			
		||||
以下事件不冒泡:blur、focus、load、unload、onmouseenter、onmouseleave。意思是,事件不会往父元素那里传递。
 | 
			
		||||
 | 
			
		||||
我们检查一个元素是否会冒泡,可以通过事件的以下参数:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```javascript
 | 
			
		||||
    event.bubbles
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -646,19 +718,19 @@ addEventListener可以捕获事件:
 | 
			
		||||
 | 
			
		||||
w3c的方法:(火狐、谷歌、IE11)
 | 
			
		||||
 | 
			
		||||
```javascipt
 | 
			
		||||
```javascript
 | 
			
		||||
    event.stopPropagation();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
IE10以下则是:
 | 
			
		||||
 | 
			
		||||
```javascipt
 | 
			
		||||
```javascript
 | 
			
		||||
event.cancelBubble = true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
兼容代码如下:
 | 
			
		||||
 | 
			
		||||
```javascipt
 | 
			
		||||
```javascript
 | 
			
		||||
   box3.onclick = function (event) {
 | 
			
		||||
 | 
			
		||||
        alert("child");
 | 
			
		||||
@ -680,13 +752,71 @@ event.cancelBubble = true
 | 
			
		||||
 | 
			
		||||
事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素。
 | 
			
		||||
 | 
			
		||||
比如说有一个列表 ul,列表之中有大量的列表项 li,我们需要在点击列表项li的时候响应一个事件。如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,效率上需要消耗很多性能。
 | 
			
		||||
比如说有一个列表 ul,列表之中有大量的列表项 li:
 | 
			
		||||
 | 
			
		||||
因此,比较好的方法就是把这个点击事件绑定到他的父层,也就是 `ul` 上,然后在执行事件的时候再去匹配判断目标元素。
 | 
			
		||||
```html
 | 
			
		||||
<ul id="parent-list">
 | 
			
		||||
    <li id="li-1">Item 1</li>
 | 
			
		||||
    <li id="li-2">Item 2</li>
 | 
			
		||||
    <li id="li-3">Item 3</li>
 | 
			
		||||
    <li id="li-4">Item 4</li>
 | 
			
		||||
    <li id="li-5">Item 5</li>
 | 
			
		||||
    <li id="li-6">Item 6</li>
 | 
			
		||||
</ul>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
所以事件委托可以减少大量的内存消耗,节约效率。
 | 
			
		||||
 | 
			
		||||
事件委托的参考链接:[JavaScript 事件委托详解](https://zhuanlan.zhihu.com/p/26536815)
 | 
			
		||||
当我们的鼠标移到Li上的时候,需要获取此Li的相关信息并飘出悬浮窗以显示详细信息,或者当某个Li被点击的时候需要触发相应的处理事件。我们通常的写法,是为每个Li都绑定类似onMouseOver或者onClick之类的事件监听:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    //每个 li 中做的事情
 | 
			
		||||
    function addListeners4Li(liNode){
 | 
			
		||||
        liNode.onclick = function clickHandler(){...};
 | 
			
		||||
        liNode.onmouseover = function mouseOverHandler(){...}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.onload = function(){
 | 
			
		||||
        var ulNode = document.getElementById("parent-list");
 | 
			
		||||
        var liNodes = ulNode.getElementByTagName("Li");
 | 
			
		||||
        for(var i=0, l = liNodes.length; i < l; i++){
 | 
			
		||||
            addListeners4Li(liNodes[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
但是,上面的做法会消耗内存和性能。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
因此,比较好的方法就是把这个点击事件绑定到他的父层,也就是 `ul` 上,然后在执行事件的时候再去匹配判断目标元素。如下:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    // 获取父节点,并为它注册click事件。 false 表示事件在冒泡阶段触发(默认)
 | 
			
		||||
    document.getElementById("parent-list").addEventListener("click", function (e) {
 | 
			
		||||
        // event.target 代表的是子元素。toUpperCase 指的是转换为大写字母
 | 
			
		||||
        if (e.target && e.target.nodeName.toUpperCase == "LI") {
 | 
			
		||||
            // 真正的处理过程在这里
 | 
			
		||||
            console.log("List item ", e.target.id, " was clicked!");
 | 
			
		||||
        }
 | 
			
		||||
    }, false);
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
上方代码,为父节点注册click事件,当子节点被点击的时候,click事件会从子节点开始**向上冒泡**。**父节点捕获到事件**之后,开始执行方法体里的内容:通过判断 e.target 拿到了被点击的子节点li。从而可以获取到相应的信息,并作处理。
 | 
			
		||||
 | 
			
		||||
换而言之,事件是在父节点上注册的,参数为false,说明事件是在冒泡阶段触发(往上传递),那就只有父节点能拿到事件,子节点是不可能拿到事件的。
 | 
			
		||||
 | 
			
		||||
所以事件委托可以减少大量的内存消耗,提高效率。
 | 
			
		||||
 | 
			
		||||
事件委托的参考链接:
 | 
			
		||||
 | 
			
		||||
- [荐 | JavaScript事件代理和委托(Delegation)](https://www.cnblogs.com/owenChen/archive/2013/02/18/2915521.html)
 | 
			
		||||
 | 
			
		||||
- [JavaScript 事件委托详解](https://zhuanlan.zhihu.com/p/26536815)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 我的公众号
 | 
			
		||||
 | 
			
		||||
@ -483,23 +483,6 @@ PS:面试提到网格布局,说明我们对新技术是有追求的。
 | 
			
		||||
答案是:**flex 布局和表格布局可以通用**,其他三个布局都不能用了。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 总结
 | 
			
		||||
 | 
			
		||||
涉及到的知识点:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(1)语义化掌握到位:每个区域用`section`、`article`代表容器、`div`代表块儿。如果通篇都用 div,那就是语义化没掌握好。
 | 
			
		||||
 | 
			
		||||
(2)页面布局理解深刻。
 | 
			
		||||
 | 
			
		||||
(3)CSS基础知识扎实。
 | 
			
		||||
 | 
			
		||||
(4)思维灵活且积极上进。题目中可以通过`网格布局`来体现。
 | 
			
		||||
 | 
			
		||||
(5)代码书写规范。注意命名。以及,上面的代码中,没有一行代码是多的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 页面布局的变通
 | 
			
		||||
 | 
			
		||||
20180305_1931.png
 | 
			
		||||
@ -509,6 +492,22 @@ PS:面试提到网格布局,说明我们对新技术是有追求的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 总结
 | 
			
		||||
 | 
			
		||||
涉及到的知识点:
 | 
			
		||||
 | 
			
		||||
(1)语义化掌握到位:每个区域用`section`、`article`代表容器、`div`代表块儿。如果通篇都用 div,那就是语义化没掌握好。
 | 
			
		||||
 | 
			
		||||
(2)页面布局理解深刻。
 | 
			
		||||
 | 
			
		||||
(3)CSS基础知识扎实。
 | 
			
		||||
 | 
			
		||||
(4)思维灵活且积极上进。题目中可以通过`网格布局`来体现。
 | 
			
		||||
 | 
			
		||||
(5)代码书写规范。注意命名。上面的代码中,没有一行代码是多的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										474
									
								
								06-前端基础/02-CSS盒模型的深度思考及BFC.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								06-前端基础/02-CSS盒模型的深度思考及BFC.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,474 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> 本文最初发表于[博客园](),并在[GitHub](https://github.com/smyhvae/Web)上持续更新**前端的系列文章**。欢迎在GitHub上关注我,一起入门和进阶前端。
 | 
			
		||||
 | 
			
		||||
> 以下是正文。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 题目:谈一谈你对CSS盒模型的认识
 | 
			
		||||
 | 
			
		||||
专业的面试,一定会问 CSS 盒模型。对于这个题目,我们要回答一下几个方面:
 | 
			
		||||
 | 
			
		||||
(1)基本概念:content、padding、margin。
 | 
			
		||||
 | 
			
		||||
(2)标准盒模型、IE盒模型的区别。不要漏说了IE盒模型,通过这个问题,可以筛选一部分人。
 | 
			
		||||
 | 
			
		||||
(3)CSS如何设置这两种模型(即:如何设置某个盒子为其中一个模型)?如果回答了上面的第二条,还会继续追问这一条。
 | 
			
		||||
 | 
			
		||||
(4)JS如何设置、获取盒模型对应的宽和高?这一步,已经有很多人答不上来了。
 | 
			
		||||
 | 
			
		||||
(5)实例题:根据盒模型解释**边距重叠**。
 | 
			
		||||
 | 
			
		||||
前四个方面是逐渐递增,第五个方面,却鲜有人知。
 | 
			
		||||
 | 
			
		||||
(6)BFC(边距重叠解决方案)或IFC。
 | 
			
		||||
 | 
			
		||||
如果能回答第五条,就会引出第六条。BFC是面试频率较高的。
 | 
			
		||||
 | 
			
		||||
**总结**:以上几点,从上到下,知识点逐渐递增,知识面从理论、CSS、JS,又回到CSS理论。
 | 
			
		||||
 | 
			
		||||
接下来,我们把上面的六条,依次讲解。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 标准盒模型和IE盒子模型
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
标准盒子模型:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
IE盒子模型:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
上图显示:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
在 CSS 盒子模型 (Box Model) 规定了元素处理元素的几种方式:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- width和height:**内容**的宽度、高度(不是盒子的宽度、高度)。
 | 
			
		||||
- padding:内边距。
 | 
			
		||||
- border:边框。
 | 
			
		||||
- margin:外边距。
 | 
			
		||||
 | 
			
		||||
CSS盒模型和IE盒模型的区别:
 | 
			
		||||
 | 
			
		||||
 - 在 <font color="#0000FF">**标准盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域**</font>的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。
 | 
			
		||||
 | 
			
		||||
 - <font color="#0000FF">**IE盒子模型**</font>中,<font color="#0000FF">**width 和 height 指的是内容区域+border+padding**</font>的宽度和高度。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## CSS如何设置这两种模型
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
代码如下:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    /* 设置当前盒子为 标准盒模型(默认) */
 | 
			
		||||
    box-sizing: content-box;
 | 
			
		||||
 | 
			
		||||
    /* 设置当前盒子为 IE盒模型 */
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
备注:盒子默认为标准盒模型。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## JS如何设置、获取盒模型对应的宽和高
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 方式一:通过DOM节点的 style 样式获取
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
	element.style.width/height;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
缺点:通过这种方式,只能获取**行内样式**,不能获取`内嵌`的样式和`外链`的样式。
 | 
			
		||||
 | 
			
		||||
这种方式有局限性,但应该了解。
 | 
			
		||||
 | 
			
		||||
### 方式二(IE独有的)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
	element.currentStyle.width/height;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取到的即时运行完之后的宽高(三种css样式都可以获取)。但这种方式只有IE独有。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 方式三(通用型)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
	window.getComputedStyle(element).width/height;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
方式三和方式二一样。只不过,方式三能兼容 Chrome、火狐。是通用型方式。
 | 
			
		||||
 | 
			
		||||
### 方式4
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
	element.getBoundingClientRect().width/height;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
此 api 的作用是:获取一个元素的绝对位置。绝对位置是视窗 viewport 左上角的绝对位置。
 | 
			
		||||
 | 
			
		||||
此 api 可以拿到四个属性:left、top、width、height。
 | 
			
		||||
 | 
			
		||||
**总结:**
 | 
			
		||||
 | 
			
		||||
上面的四种方式,要求能说出来区别,以及哪个的通用型更强。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## margin塌陷/margin重叠
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**标准文档流中,竖直方向的margin不叠加,只取较大的值作为margin**(水平方向的margin是可以叠加的,即水平方向没有塌陷现象)。
 | 
			
		||||
 | 
			
		||||
PS:如果不在标准流,比如盒子都浮动了,那么两个盒子之间是没有margin重叠的现象的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
我们来看几个例子。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 兄弟元素之间
 | 
			
		||||
 | 
			
		||||
如下图所示:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 子元素和父元素之间
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <style>
 | 
			
		||||
 | 
			
		||||
        * {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .father {
 | 
			
		||||
            background: green;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 给儿子设置margin-top为10像素 */
 | 
			
		||||
        .son {
 | 
			
		||||
            height: 100px;
 | 
			
		||||
            margin-top: 10px;
 | 
			
		||||
            background: red;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div class="father">
 | 
			
		||||
    <div class="son"></div>
 | 
			
		||||
</div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的代码中,儿子的height是 100px,magin-top 是10px。注意,此时父亲的 height 是100,而不是110。因为儿子和父亲在竖直方向上,共一个margin。
 | 
			
		||||
 | 
			
		||||
儿子这个盒子:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
父亲这个盒子:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
上方代码中,如果我们给父亲设置一个属性:`overflow: hidden`,就可以避免这个问题,此时父亲的高度是110px,这个用到的就是BFC(下一段讲解)。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 善于使用父亲的padding,而不是儿子的margin
 | 
			
		||||
 | 
			
		||||
> 其实,这一小段讲的内容与上一小段相同,都是讲父子之间的margin重叠。
 | 
			
		||||
 | 
			
		||||
我们来看一个奇怪的现象。现在有下面这样一个结构:(div中放一个p)
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
	<div>
 | 
			
		||||
		<p></p>
 | 
			
		||||
	</div>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的结构中,我们尝试通过给儿子`p`一个`margin-top:50px;`的属性,让其与父亲保持50px的上边距。结果却看到了下面的奇怪的现象:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
此时我们给父亲div加一个border属性,就正常了:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
如果父亲没有border,那么儿子的margin实际上踹的是“流”,踹的是这“行”。所以,父亲整体也掉下来了。
 | 
			
		||||
 | 
			
		||||
**margin这个属性,本质上描述的是兄弟和兄弟之间的距离; 最好不要用这个marign表达父子之间的距离。**
 | 
			
		||||
 | 
			
		||||
所以,如果要表达父子之间的距离,我们一定要善于使用父亲的padding,而不是儿子的margin。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## BFC(边距重叠解决方案)
 | 
			
		||||
 | 
			
		||||
### BFC的概念
 | 
			
		||||
 | 
			
		||||
BFC(Block Formatting Context):块级格式化上下文。你可以把它理解成一个独立的区域。
 | 
			
		||||
 | 
			
		||||
另外还有个概念叫IFC。不过,BFC问得更多。
 | 
			
		||||
 | 
			
		||||
### BFC 的原理/BFC的布局规则【非常重要】
 | 
			
		||||
 | 
			
		||||
BFC 的原理,其实也就是 BFC 的渲染规则(能说出以下四点就够了)。包括:
 | 
			
		||||
 | 
			
		||||
- (1)BFC **里面的**元素,在垂直方向,**边距会发生重叠**。
 | 
			
		||||
 | 
			
		||||
- (2)BFC在页面中是独立的容器,外面的元素不会影响里面的元素,反之亦然。(稍后看`举例1`)
 | 
			
		||||
 | 
			
		||||
- (3)**BFC区域不与旁边的`float box`区域重叠**。(可以用来清除浮动带来的影响)。(稍后看`举例2`)
 | 
			
		||||
 | 
			
		||||
- (4)计算BFC的高度时,浮动的子元素也参与计算。(稍后看`举例3`)
 | 
			
		||||
 | 
			
		||||
### 如何生成BFC
 | 
			
		||||
 | 
			
		||||
有以下几种方法:
 | 
			
		||||
 | 
			
		||||
- 方法1:overflow: 不为vidible,可以让属性是 hidden、auto。【最常用】
 | 
			
		||||
 | 
			
		||||
- 方法2:浮动中:float的属性值不为none。意思是,只要设置了浮动,当前元素就创建了BFC。
 | 
			
		||||
 | 
			
		||||
- 方法3:定位中:只要posiiton的值不是 static或者是relative即可,可以是`absolute`或`fixed`,也就生成了一个BFC。
 | 
			
		||||
 | 
			
		||||
- 方法4:display为inline-block, table-cell, table-caption, flex, inline-flex
 | 
			
		||||
 | 
			
		||||
参考链接:
 | 
			
		||||
 | 
			
		||||
- [BFC原理详解](https://segmentfault.com/a/1190000006740129)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- [BFC详解](https://www.jianshu.com/p/bf927bc1bed4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- [前端精选文摘:BFC 神奇背后的原理](https://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
下面来看几个例子,看看如何生成BFC。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### BFC 的应用
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**举例1:**解决 margin 重叠
 | 
			
		||||
 | 
			
		||||
当父元素和子元素发生 margin 重叠时,解决办法:**给子元素增加一个父元素,给这个父元素创建BFC**。
 | 
			
		||||
 | 
			
		||||
比如说,针对下面这样一个 div 结构:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<div class="father">
 | 
			
		||||
    <p class="son">
 | 
			
		||||
    </p>
 | 
			
		||||
</div>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的div结构中,如果父元素和子元素发生margin重叠,我们可以给子元素创建一个 BFC,就解决了:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<div class="father">
 | 
			
		||||
    <p class="son" style="overflow: hidden">
 | 
			
		||||
    </p>
 | 
			
		||||
</div>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
因为**第二条:BFC区域是一个独立的区域,不会影响外面的元素**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**举例2**:BFC区域不与float区域重叠:
 | 
			
		||||
 | 
			
		||||
针对下面这样一个div结构;
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <style>
 | 
			
		||||
 | 
			
		||||
        .father-layout {
 | 
			
		||||
            background: pink;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .father-layout .left {
 | 
			
		||||
            float: left;
 | 
			
		||||
            width: 100px;
 | 
			
		||||
            height: 100px;
 | 
			
		||||
            background: green;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .father-layout .right {
 | 
			
		||||
            height: 150px;  /*右侧标准流里的元素,比左侧浮动的元素要高*/
 | 
			
		||||
            background: red;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<section class="father-layout">
 | 
			
		||||
    <div class="left">
 | 
			
		||||
        左侧,生命壹号
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="right">
 | 
			
		||||
        右侧,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,
 | 
			
		||||
    </div>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
效果如下:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
上图中,由于右侧标准流里的元素,比左侧浮动的元素要高,导致右侧有一部分会跑到左边的下面去。
 | 
			
		||||
 | 
			
		||||
**如果要解决这个问题,可以将右侧的元素创建BFC**,因为**第三条:BFC区域不与`float box`区域重叠**。解决办法如下:(将right区域添加overflow属性)
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
    <div class="right" style="overflow: hidden">
 | 
			
		||||
        右侧,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,smyhvae,
 | 
			
		||||
    </div>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
上图表明,解决之后,`father-layout`的背景色显现出来了,说明问题解决了。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**举例3:**清除浮动
 | 
			
		||||
 | 
			
		||||
现在有下面这样的结构:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
    <style>
 | 
			
		||||
 | 
			
		||||
        .father {
 | 
			
		||||
            background: pink;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .son {
 | 
			
		||||
            float: left;
 | 
			
		||||
            background: green;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<section class="father">
 | 
			
		||||
    <div class="son">
 | 
			
		||||
        生命壹号
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
</section>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
效果如下:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
上面的代码中,儿子浮动了,但由于父亲没有设置高度,导致看不到父亲的背景色(此时父亲的高度为0)。正所谓**有高度的盒子,才能关住浮动**。
 | 
			
		||||
 | 
			
		||||
如果想要清除浮动带来的影响,方法一是给父亲设置高度,然后采用隔墙法。方法二是 BFC:给父亲增加 `overflow=hidden`属性即可, 增加之后,效果如下:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
为什么父元素成为BFC之后,就有了高度呢?这就回到了**第四条:计算BFC的高度时,浮动元素也参与计算**。意思是,**在计算BFC的高度时,子元素的float box也会参与计算**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 我的公众号
 | 
			
		||||
 | 
			
		||||
想学习<font color=#0000ff>**代码之外的软技能**</font>?不妨关注我的微信公众号:**生命团队**(id:`vitateam`)。
 | 
			
		||||
 | 
			
		||||
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										435
									
								
								06-前端基础/03-DOM事件的总结.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										435
									
								
								06-前端基础/03-DOM事件的总结.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,435 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 前言
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
要学习事件的基础内容,请看先本人的这篇基础文章:
 | 
			
		||||
 | 
			
		||||
- [JavaScript基础:事件对象Event和冒泡](https://github.com/smyhvae/Web/blob/master/03-JavaScript/09-JavaScript%E5%9F%BA%E7%A1%80%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%AF%B9%E8%B1%A1Event%E5%92%8C%E5%86%92%E6%B3%A1.md)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
知识难度不大,只是大家没有系统地学习。
 | 
			
		||||
 | 
			
		||||
**知识点主要包括以下几个方面:**
 | 
			
		||||
 | 
			
		||||
- 基本概念:DOM事件的级别
 | 
			
		||||
 | 
			
		||||
面试不会直接问你,DOM有几个级别。但会在题目中体现:“请用DOM2 ....”。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- DOM事件模型、DOM事件流
 | 
			
		||||
 | 
			
		||||
面试官如果问你“**DOM事件模型**”,你不一定知道怎么回事。其实说的就是**捕获和冒泡**。
 | 
			
		||||
 | 
			
		||||
**DOM事件流**,指的是事件传递的**三个阶段**。
 | 
			
		||||
 | 
			
		||||
- 描述DOM事件捕获的具体流程
 | 
			
		||||
 | 
			
		||||
讲的是事件的传递顺序。参数为false(默认)、参数为true,各自代表事件在什么阶段触发。
 | 
			
		||||
 | 
			
		||||
能回答出来的人,寥寥无几。也许有些人可以说出一大半,但是一字不落的人,极少。
 | 
			
		||||
 | 
			
		||||
- Event对象的常见应用(Event的常用api方法)
 | 
			
		||||
 | 
			
		||||
DOM事件的知识点,一方面包括事件的流程;另一方面就是:怎么去注册事件,也就是监听用户的交互行为。第三点:在响应时,Event对象是非常重要的。
 | 
			
		||||
 | 
			
		||||
- 自定义事件(非常重要)
 | 
			
		||||
 | 
			
		||||
一般人可以讲出事件和注册事件,但是如果让你讲**自定义事件**,能知道的人,就更少了。
 | 
			
		||||
 | 
			
		||||
- 事件委托
 | 
			
		||||
 | 
			
		||||
业务中经常用到。
 | 
			
		||||
 | 
			
		||||
下面分别讲解。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## DOM事件的级别
 | 
			
		||||
 | 
			
		||||
DOM事件的级别,准确来说,是**DOM标准**定义的级别。包括:
 | 
			
		||||
 | 
			
		||||
**DOM0的写法:**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    element.onclick = function () {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
上面的代码是在 js 中的写法;如果要在html中写,写法是:在onclick属性中,加 js 语句。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**DOM2的写法:**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    element.addEventListener('click', function () {
 | 
			
		||||
 | 
			
		||||
    }, false);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
【重要】上面的第三参数中,**true**表示事件在**捕获阶段**触发,**false**表示事件在**冒泡阶段**触发(默认)。如果不写,则默认为false。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**DOM3的写法:**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    element.addEventListener('keyup', function () {
 | 
			
		||||
 | 
			
		||||
    }, false);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
DOM3中,增加了很多事件类型,比如鼠标事件、键盘事件等。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PS:为何事件没有DOM1的写法呢?因为,DOM1标准制定的时候,没有涉及与事件相关的内容。
 | 
			
		||||
 | 
			
		||||
**总结:**关于“DOM事件的级别”,能回答出以上内容即可,不会出题目让你做。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## DOM事件模型、DOM事件流
 | 
			
		||||
 | 
			
		||||
### DOM事件模型
 | 
			
		||||
 | 
			
		||||
DOM事件模型讲的就是**捕获和冒泡**,一般人都能回答出来。
 | 
			
		||||
 | 
			
		||||
- 捕获:从上往下。
 | 
			
		||||
 | 
			
		||||
- 冒泡:从下(目标元素)往上。
 | 
			
		||||
 | 
			
		||||
### DOM事件流
 | 
			
		||||
 | 
			
		||||
DOM事件流讲的就是:浏览器在于当前页面做交互时,这个事件是怎么传递到页面上的。
 | 
			
		||||
 | 
			
		||||
类似于Android里面的事件传递。
 | 
			
		||||
 | 
			
		||||
完整的事件流,分三个阶段:
 | 
			
		||||
 | 
			
		||||
- (1)捕获:从 window 对象传到 目标元素。
 | 
			
		||||
 | 
			
		||||
- (2)目标阶段:事件通过捕获,到达目标元素,这个阶段就是目标阶段。
 | 
			
		||||
 | 
			
		||||
- (3)冒泡:从**目标元素**传到 Window 对象。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
20180306_1058.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 描述DOM事件捕获的具体流程
 | 
			
		||||
 | 
			
		||||
> 很少有人能说完整。
 | 
			
		||||
 | 
			
		||||
### 捕获的流程
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
20180306_1103.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**说明**:捕获阶段,事件依次传递的顺序是:window --> document --> html--> body --> 父元素、子元素、目标元素。
 | 
			
		||||
 | 
			
		||||
PS1:第一个接收到事件的对象是 **window**(有人会说body,有人会说html,这都是错误的)。
 | 
			
		||||
 | 
			
		||||
PS2:JS中涉及到DOM对象时,有两个对象最常用:window、doucument。它们俩也是最先获取到事件的。
 | 
			
		||||
 | 
			
		||||
代码如下:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    window.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 window");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 document");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.documentElement.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 html");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    document.body.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 body");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    fatherBox.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 father");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
    childBox.addEventListener("click", function () {
 | 
			
		||||
        alert("捕获 child");
 | 
			
		||||
    }, true);
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**补充一个知识点:**
 | 
			
		||||
 | 
			
		||||
在 js中:
 | 
			
		||||
 | 
			
		||||
- 如果想获取 `body` 节点,方法是:`document.body`;
 | 
			
		||||
 | 
			
		||||
- 但是,如果想获取 `html`节点,方法是`document.documentElement`。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 冒泡的流程
 | 
			
		||||
 | 
			
		||||
与捕获的流程相反
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Event对象的常见 api 方法
 | 
			
		||||
 | 
			
		||||
用户做的是什么操作(比如,是敲键盘了,还是点击鼠标了),这些事件基本都是通过Event对象拿到的。这些都比较简单,我们就不讲了。我们来看看下面这几个方法:
 | 
			
		||||
 | 
			
		||||
### 方法一
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
解释:阻止默认事件。
 | 
			
		||||
 | 
			
		||||
比如,已知`<a>`标签绑定了click事件,此时,如果给`<a>`设置了这个方法,就阻止了链接的默认跳转。
 | 
			
		||||
 | 
			
		||||
### 方法二:阻止冒泡
 | 
			
		||||
 | 
			
		||||
这个在业务中很常见。
 | 
			
		||||
 | 
			
		||||
有的时候,业务中不需要事件进行冒泡。比如说,业务这样要求:单击子元素做事件A,单击父元素做事件B,如果不阻止冒泡的话,出现的问题是:单击子元素时,子元素和父元素都会做事件A。这个时候,就要用到阻止冒泡了。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
w3c的方法:(火狐、谷歌、IE11)
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    event.stopPropagation();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
IE10以下则是:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
	event.cancelBubble = true;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
兼容代码如下:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
   box3.onclick = function (event) {
 | 
			
		||||
 | 
			
		||||
        alert("child");
 | 
			
		||||
 | 
			
		||||
        //阻止冒泡
 | 
			
		||||
        event = event || window.event;
 | 
			
		||||
 | 
			
		||||
        if (event && event.stopPropagation) {
 | 
			
		||||
            event.stopPropagation();
 | 
			
		||||
        } else {
 | 
			
		||||
            event.cancelBubble = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上方代码中,我们对box3进行了阻止冒泡,产生的效果是:事件不会继续传递到 father、grandfather、body了。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 方法三:设置事件优先级
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    event.stopImmediatePropagation();
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
这个方法比较长,一般人没听说过。解释如下:
 | 
			
		||||
 | 
			
		||||
比如说,我用addEventListener给某按钮同时注册了事件A、事件B。此时,如果我单击按钮,就会依次执行事件A和事件B。现在要求:单击按钮时,只执行事件A,不执行事件B。该怎么做呢?这是时候,就可以用到`stopImmediatePropagation`方法了。做法是:在事件A的响应函数中加入这句话。
 | 
			
		||||
 | 
			
		||||
大家要记住 event 有这个方法。
 | 
			
		||||
 | 
			
		||||
### 属性4、属性5(事件委托中用到)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
    event.currentTarget   //当前所绑定的事件对象。在事件委托中,指的是【父元素】。
 | 
			
		||||
 | 
			
		||||
    event.target  //当前被点击的元素。在事件委托中,指的是【子元素】。
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面这两个属性,在事件委托中经常用到。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**总结**:上面这几项,非常重要,但是容易弄混淆。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 自定义事件
 | 
			
		||||
 | 
			
		||||
自定义事件的代码如下:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    var myEvent = new Event('clickTest');
 | 
			
		||||
    element.addEventListener('clickTest', function () {
 | 
			
		||||
        console.log('smyhvae');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
	//元素注册事件
 | 
			
		||||
    element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent,不是写 事件名 clickTest
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面这个事件是定义完了之后,就直接自动触发了。在正常的业务中,这个事件一般是和别的事件结合用的。比如延时器设置按钮的动作:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    var myEvent = new Event('clickTest');
 | 
			
		||||
 | 
			
		||||
    element.addEventListener('clickTest', function () {
 | 
			
		||||
        console.log('smyhvae');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    setTimeout(function () {
 | 
			
		||||
        element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent,不是写 事件名 clickTest
 | 
			
		||||
    }, 1000);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 事件委托
 | 
			
		||||
 | 
			
		||||
参考本人这篇文章的最后一段:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- [JavaScript基础:事件对象Event和冒泡](https://github.com/smyhvae/Web/blob/master/03-JavaScript/09-JavaScript%E5%9F%BA%E7%A1%80%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%AF%B9%E8%B1%A1Event%E5%92%8C%E5%86%92%E6%B3%A1.md)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								06-前端基础/04-HTTP协议.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								06-前端基础/04-HTTP协议.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
一面中,如果有笔试,考HTTP协议的可能性较大。
 | 
			
		||||
 | 
			
		||||
## 前言
 | 
			
		||||
 | 
			
		||||
一面内容:
 | 
			
		||||
 | 
			
		||||
- HTTP协议的主要特点
 | 
			
		||||
 | 
			
		||||
- HTTP报文的组成部分
 | 
			
		||||
 | 
			
		||||
- HTTP方法
 | 
			
		||||
 | 
			
		||||
- get 和 post的区别
 | 
			
		||||
 | 
			
		||||
- HTTP状态码
 | 
			
		||||
 | 
			
		||||
- 什么是持久连接
 | 
			
		||||
 | 
			
		||||
- 什么是管线化
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
二面内容;
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 题目:谈一谈你对CSS盒模型的认识
 | 
			
		||||
 | 
			
		||||
专业的面试,一定会问 CSS 盒模型。对于这个题目,我们要回答一下几个方面:
 | 
			
		||||
 | 
			
		||||
(1)基本概念:content、padding、margin。
 | 
			
		||||
 | 
			
		||||
(2)标准盒模型、IE盒模型的区别。不要漏说了IE盒模型,通过这个问题,可以筛选一部分人。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(3)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,12 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 2018-03-06
 | 
			
		||||
 | 
			
		||||
- [我遇到的前端面试题2017](https://segmentfault.com/a/1190000011091907)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
里面有很多面试跳槽里的内容。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user