DOM操作及性能优化

 DOM节点操作

prototype 和 attribute 的区别

  • prototype:修改对象属性,不会体现到 html 结构中
  • attribute:修改 html 属性,会改变 html 结构
  • 两者都有可能引起 DOM 重新渲染
const pList = document.querySelectorAll('p')
const p1 = pList[0]

// prototype
p1.style.width = '100px'
console.log(p1.style.width);
p1.className = 'red'
console.log(p1.className);
console.log(p1.nodeName);
console.log(p1.nodeType);
// attribute
p1.setAttribute('data-name','imooc')
console.log(p1.getAttribute('data-name'));
p1.setAttribute('style','font-size: 50px')
console.log(p1.getAttribute('style'));

DOM结构操作

常见的DOM结构操作有 新建节点( createElement() )、删除节点( 父元素.removeChild() )、插入节点/移动节点 ( appendChild() ) 、  获取父节点 ( 子元素.parentNode() ) 、 获取子元素(  父元素.ChildNodes() )

// dom结构操作
const div0 = document.getElementById('div0')
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')

// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is p'
//插入节点
div1.appendChild(newP)

// 移动节点 -- 对已有节点用appendChild(),会将该节点移动,该节点原位置就会出现连续两个#text 父元素.childNodes
const p1 = document.getElementById('p1')
div2.appendChild(p1);

// 获取父元素
console.log(p1.parentNode);

// 获取子元素列表
console.log( div0.childNodes );
const div0ChildNode = div0.childNodes
// 筛选nodeType为1的子节点
const div0ChildNodeP = Array.prototype.slice.call(div0.childNodes).filter(child => {
    if(child.nodeType === 1) {
        return true
    }
    return false
})
console.log(div0ChildNodeP);

//删除子节点
div2.removeChild(p1)
console.log(div2.childNodes);


DOM性能

  • DOM操作非常"昂贵",避免频繁的DOM操作
  •  对DOM查询做缓存
  •  将频繁操作改为一次性操作
  • DOM结果做缓存
// 不缓存 DOM 查询结果
for(let i = 0; i < document.getElementsByTagName('p').length; i++) {
    //每次循环,都会计算 length ,频繁进行 DOM 查询
}

// 缓存 DOM 结果
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i = 0; i < length; i++) {
    //缓存length,只做一次DOM查询
}
  •  将频繁操作改为一次性操作
// 频繁依次操作
const list = document.getElementById('list')

for(let i = 0; i < 10; i++) {
    const li = document.createElement('li')
    li.innerHTML = `list item ${i}`
    list.appendChild(li)
}
// 将频发操作改为一次性操作
// 创建一个文档片段,此时还没有插入到 DOM 树,不会影响性能
const frag = document.createDocumentFragment()

// 执行插入
for(let x = 0; x < 10; x++) {
    const li = document.createElement('li')
    li.innerHTML = `list item ${x}`
    frag.appendChild(li)
}

// 都完成后,在插入到 DOM 树中
list.appendChild(frag)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值