margin塌陷
:(为了解决段落之间垂直方向的间距问题而设计的,因此只有垂直塌陷)
块级元素才会发生塌陷,行内元素和行内块级元素都不会发生塌陷
外边距的计算方法:正数&&正数 取最大 正数&&负数 取和 负数&&负数 取绝对值最大的数
父子元素默认顶对齐:AB顶对齐,且AB共享外边距,如果分别给A和B分别设置margin-top:10px和margin-top:20px;则AB会一起下移20px,
想让B下移,
1)可以给A设置position:ralative给B设置position:absolute;margin-top:20px;
2)把B设置成行内元素(需要为行内块级元素设置宽高),display:inline-block,margin-top:20px
3)B设置成position:relative top:20px
4)给A overflow:hidden来触发BFC
5)给A设置padding-top:20px;
6)给A设置border-top:5px solid yellow;并给B设置margin-top:20px
清除浮动
浮动塌陷:为元素设置浮动后,元素会脱离文档流,如果包含块没有设置高度,或者高度自适应时,浮动元素的高度不会被计算进去。
1) 在父元素内部最下方创建空元素,并给空元素设置clear:both (会产生大量空元素,浪费资源)
2)给父元素添加overflow:hidden或overflow:auto创建BFC
3)添加伪元素.father::after{
content:'',
display:block;
clear:both;
}
BFC
块级格式化上下文特性
1)BFC是页面上一个隔离的独立容器,容器的子元素不会影响到外面的元素
2)BFC内浮动元素的高度会被计算进去,可用于清除浮动。
3)box垂直方向的距离由margin决定,会叠加,可用于解决margin塌陷
4)BFC区域不会与浮动元素重叠
触发条件:
position:absolute/fixed (元素会变成inline-block)
float:right/left (元素会变成inline-block)
display:inline-block/table-cell/flex
overflow:hidden/auto/scroll
HTML是一个最大的BFC
什么是虚拟DOM
虚拟DOM是一个能代表DOM树的对象,通常包含标签名,标签上的属性,事件监听和子元素
虚拟dom优点:
1)减少dom操作
(a.向页面中添加1000个节点,js的dom要一个一个的添加到页面中操作1000次,虚拟dom可以一次性的放到页面上,虚拟dom只需要操作一次 b.dom diff可以区分新旧,减少多余操作)
2)能跨平台渲染
虚拟DOM不仅可以变成DOM,还可以变成小程序,IOS应用,安卓应用等。
虚拟dom缺点:
需要额外的创建函数来创建虚拟DOM,react里面用的是createElement,vue用的h
可以通过JSX来简化成XML写法,写成标签之后就需要额外的构建过程,严重依赖打包工具,react用bable,vue用vue-loader
Diff对比流程(vue2.vue3???未完)
当数据发生改变时,调用patch方法
patch方法,先通过sameVnode方法比较同一层的两个虚拟节点是否是同一类型
是—>执行patchVnode方法进行深层对比
否—>直接将整个节点替换成新dom节点
sameVnode:判断同一类型的方法
//先判断key值-标签名-是否都为注释节点(document.createComment(data)创建注释节点)-是否都定义了data-当标签为input时type是否相同
function sameVnode(oldVnode, newVnode) {
return (
oldVnode.key === newVnode.key && // key值是否一样
oldVnode.tagName === newVnode.tagName && // 标签名是否一样
oldVnode.isComment === newVnode.isComment && // 是否都为注释节点
isDef(oldVnode.data) === isDef(newVnode.data) && // 是否都定义了data
sameInputType(oldVnode, newVnode) // 当标签为input时,type必须是否相同
)
}
patchVnode深层判断
1)找到对应的真实dom命名为el
2) oldVnode和newVnode为同一对象 return
3)oldVnode和newVnode都存在文本节点,且不相等,则将el的文本节点设置为newVnode的文本节点
4)old有子节点,new没有,删除el的子节点
new有自己点,old没有,则将new真实化后添加到el
5)old和new都有子节点,则执行updateChildren比较子节点
updateChildren
1.oldS与newS比,相同则把oldS节点移动到newS对应位置,OldS++,newS++
2.oldS与newE
3.oldE与newS
4oldE与newE
5.以上都匹配失败,在新节点中的key去找旧节点中可以复用的位置
tomorrow 虚拟dom转真实dom手撕