JS中的DOM节点类型以及浅谈数据绑定和DOM回流

js中的常用的节点类型有哪些?

节点类型nodeTypenodeNamenodeValue
Element(元素节点)1元素名null
Attr(属性节点)2属性名称属性值
Text(文本节点)3#text文本内容
CDATASection(CDATA节点)4#cdata-section节点的内容
EntityReference(实体引用名称节点)5实体引用名称null
Entity(实体名称节点)6实体名称null
ProcessingInstruction(处理指令节点)7target节点内容
Comment(注释节点)8#comment注释内容
Document(根节点)9#documentnull
DocumentType(文档类型节点)10文档类型名称null
DocumentFragment(文档片段节点)11#document片段null
Notation(DTD声明节点)12符号名称null

数据绑定

  • 第一种方式:利用动态创建元素节点并把它追加到页面中的这种方式是实现数据绑定
for(var i = 0; i <goods.length; i++) {
        var item = goods[i];

        var oLi = document.createElement('li');
        var oImg = document.createElement('img');
        var oP1 = document.createElement('p');
        var oP2 = document.createElement('p');
        var oP3 = document.createElement('p');
        var oP4 = document.createElement('p');

        oImg.src = item.img;
        oP1.innerHTML = item.title;
        oP2.innerHTML = "上架时间:" + item.time;
        oP3.innerHTML = "价格:" + item.price;
        oP4.innerHTML = "热度:" + item.hot;

        oLi.appendChild(oImg);
        oLi.appendChild(oP1);
        oLi.appendChild(oP2);
        oLi.appendChild(oP3);
        oLi.appendChild(oP4);

        goodslist.appendChild(oLi);
    }

优势:把需要动态绑定的数据一个一个的追加到页面中,对原来的元素没有任何影响(DOM映射)
弊端:每次创建一个元素都要添加到页面中,每一都会引发一次DOM回流,最终导致计算次数太多,影响性能。

  • 第二种方式:字符串拼接的方式,循环需要绑定的数据,然后把需要绑定的数据以字符串的形式拼接到一起,拼接完成后,一次性添加到页面中,减少了DOM回流
 let bind_data = function (data) {
        let str = ``;
        for (let i = 0; i < data.length; i++) {
            let { title, price, time, hot, img } = data[i];
            str += `
         <li data-time="${time}" data-price="${price}" data-hot="${hot}">
            <img src="${img}" alt="">
            <span>${title}</span>
            <span>上架时间:${time}</span>
            <span>热度:${hot}</span>
            <span>价格:${price}</span>
        </li>
`;
        }
        oList.innerHTML = str;
  • 第三种方式,文档碎片动态绑定数据,在所有的节点类型中,只有文档碎片节点DocumentFragment在文档中没有对应的标记,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。(既保证对原有的不影响,也减少了DOM的回流 )
let tempFragment = document.createDocumentFragment();//创建一个文档碎片
        for (let i = 0; i < newAry.length; i++) {
            tempFragment.appendChild(newAry[i]);//循环遍历,添加到这个碎片中
        }
        oList.appendChild(tempFragment);//最后一次性添加到页面中

什么是DOM回流?

  • 回流(重排 reflow):当页面中的HTML结构发生改变(增加、删除元素、位置发生改变等等),只要结构发生改变,浏览器都需要从新的计算一遍最新的dom结构,从新的对当前的页面进行渲染
  • 重绘:某一个元素的部分样式发生改变了(例如:背景颜色),浏览器只需要从新渲染当前元素即可

重排(回流)和重绘读写分离

浏览器渲染页面的时候是按照"先创建DOM数=>在加载CSS=>生成渲染数 RENDER TREE=>把渲染数交给浏览器(CPU)进行绘制",如果后期我们改变了元素的样式(但是没有改变元素的大小和位置),浏览器会把当前元素重新生成渲染数,然后进行重新渲染,这个机制是重绘,但是一旦元素的位置或者大小等发生改变,浏览器就要从DOM数重新计算渲染,这个机制是重排(回流)。无论是重排还是重绘都非常的消耗性能。在我的以前项目中,我特意的注重了这个问题,尽量减少操作DOM引发的回流和重绘问题,常用的解决方案:
1、需要动态的向页面追加元素的时候,基于文档碎片或者先把需要追加的所有元素拼接成字符串最后统一追加到页面中
2、读写分离:把统一修改样式都放到一起执行,新版浏览器都有一个自己检测的机制,如果发现紧挨着的操作也是修改元素的样式,会把所有修改的是存起来,直到遇到非修改样式的操作,会把之前存储的统一执行,引发一次重排和重绘,当然还有一些其他的办法 ,这些是最长注意的,我认为减少DOM回流重绘是非常重要的性能优化手段之一

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值