先说下真实的DOM:
我们学习的原生js和jquery都是通过操作真实的DOM进行页面功能和是数据渲染的实现。
例如:
原生js中会有
<script>
//通过ID获取(getElementById)
//通过name属性(getElementsByName)
//通过标签名(getElementsByTagName)
//通过类名(getElementsByClassName)
//通过选择器获取一个元素(querySelector)
//通过选择器获取一组元素(querySelectorAll)
//获取html的方法(document.documentElement)
//document.documentElement是专门获取html这个标签的
//获取body的方法(document.body)
//document.body是专门获取body这个标签的。
</script>Jquery中有
<script>
//append(): 向每个匹配的元素内部追加内容.
// appendTo(): 将所有匹配的元素追加到指定的元素中
// prepend(): 向每个匹配的元素内部前置内容.
// prependTo(): 将所有匹配的元素前置到指定的元素中
// after(): 在每个匹配的元素之后插入内容.
// insertAfter(): 将所有匹配的元素插入到指定元素的后面.
// before(): 在每个匹配的元素之前插入内容.
// insertBefore(): 将所有匹配的元素插入到指定元素的前面.
// 等等等......
</script>直接操作真实的DOM节点的话,浏览器会一个一个从头到尾执行一边。比如 有A、B、C、D四个人。
先让A站第一个,在让B站第二个,C站第三个,但是我最后让D站第一个,然后其他就往后移
这样其他三个人之前的排位置的时间算是白花了,还要往旁边挪开,空出一个位置给D。
四个人还好,但是要是四百个人呢,399个人需要移动位置,真的是有点浪费时间和精力了。
所以那有没有更好的办法呢?
这个时候虚拟DOM就显得更加优秀了。
虚拟DOM是一个js对象。怎么理解这个js对象呢?
我们都知道对象使用之前要定义,不定义直接使用的话,就会报错。也就是说是用不了。
而这个虚拟DOM呢,就像是一个空对象,操作虚拟DOM就像是网这个对象里面添加属性和对应的属性值。对象内的属性全部定义好了之后,
再按照这个对象里面的内容,全部转化,输送给真实的DOM,让其在页面中渲染出来。
因为这个对象不可能一直保持不变,在开发中出现代码的增删改是很正常的现象。
操作的是虚拟DOM,那是所以只要对象一改动,就能马上反应到虚拟DOM上。
那又是如何反应的呢?
这里面又牵扯到一个概念就是diff算法。
反应的方式就是通过diff算法来实现的。
对象更新时会生成一个新DOM对象,diff算法就是把新的DOM对象和老的DOM对象进行比较,
1、发现新属性里没有老属性,那么老属性就直接卸载;新属性直接安装
2、发现新属性的和老属性全部相同(属性值也有可能是对象,也要往下面核对),那么就保留
3、发现同一个属性里,新和老的有些值不同,那么则要排列比较,看哪些修改了,哪些是新增的,哪些是删除的。
这样在一定程度上也比更深的遍历发现同更加节约时间。
因为老对象的改变,则会使真实的DOM也会发生改变,这样就在页面上实现了刷新
在上面3的内容中,我们又可以得到一个知识点:那就是虚拟DOM的key值。
key值就相当于给这些属性值加上了一个标签,这样我们就可以通过这个key值去找到对应的值与之比较或是别的操作。
所以,这里我们就要求key值最好是独一无二的。
如果用index作为key值得话,如果值得位置有变动,那么对应的index指向的就是变动后的值,所以变动后的值的位置和原来的位置是不是一样,不能确定
因此,index作为key值会有可能会存在一定偏差。
















