JavaScript DOM(二) 案例只留下案例名称,需复习的话,下载素材 ,按名字搜索后可找到文件
节点操作 通过上文可知获取元素可以来利用 DOM 提供的方法来获取元素,如 getElementById、querySelector 等方法,但是也可以利用节点关系来获取元素
节点概述
节点层级 利用 DOM 树可以把节点划分为不同的层级关系,如父子层级、兄弟层级
父节点 node.parentNode
1 2 3 4 5 //node.parentNode var son = document.querySelector(".son"); console.log(son.parentNode);
parentNode 属性可返回最近的一个父节点
指定的节点没有父节点则返回 null(测试只有 document.parentNode 会返回 null,body 里的节点的父节点可以是 body)
子节点
parentNode.childNodes
返回包含指定节点的子节点的集合,包含元素节点、文本节点等
1 2 3 4 5 6 7 8 9 <div class="father"> <div class="son"></div> </div> <script> var father = document.querySelector(".father"); console.log(father.childNodes); </script>
结果:
这种方法要获取元素节点,可以遍历所有节点,利用元素节点的 nodeType 为 1 的性质选出来。但是很麻烦。 2. parentNode.children
返回包含指定节点的子元素节点的集合,只返回元素节点
1 2 3 4 5 6 7 8 9 10 <div class="father"> <div class="son1"></div> <div class="son2"></div> </div> <script> var father = document.querySelector(".father"); console.log(father.children); </script>
结果:
3. parentNode.firstChild
返回第一个子节点,也是所有的子节点中的第一个节点 4. parentNode.lastChild
返回最后一个子节点,也是所有的子节点中的最后一个节点 5. parentNode.firstElementChild
返回第一个子元素节点 6. parentNode.lastElementChild
返回最后一个子元素节点
也可以:parentNode.children[0]获取第一个子元素节点;parentNode.children[parentNode.children.length -1]获取最后一个子元素节点
案例 新浪下拉菜单
兄弟节点 两种方式,分别是所有的节点和元素节点。和获取子节点相似。
node.nextSibling
返回下一个兄弟节点,包含所有的节点。 2. node.previousSibling
返回下一个兄弟节点,包含所有的节点。 3. node.nextElementSibling
返回下一个兄弟元素节点 4. node.previousElementSibling
返回下一个兄弟元素节点
其中,3、4 有兼容性问题,IE9 以上才支持,可以封装兼容性函数
创建节点 document.createElement(‘tagName’) 创建的元素原本不存在,是动态生成的,又被称为动态创建元素节点
1 2 3 var div = document.createElement("div");
添加节点 创建节点后,创建的节点并不会出现,而需要把节点添加上去才可以。添加节点主要是先找到要添加的位置的父节点,然后才添加进去。有两种方法
node.appendChild(child)
将节点 child 添加到指定的父节点 node 的子节点末尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <body> <div class="box"> <div class="one"></div> <div class="two"></div> </div> <script> var div = document.createElement("div"); div.className = "three"; var box = document.querySelector(".box"); box.appendChild(div); </script> </body>
结果:
2. node.insertBefore(child, 指定元素);
将节点 child 添加到父节点 node 的指定子节点前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body> <div class="box"> <div class="one"></div> <div class="two"></div> </div> <script> var div = document.createElement("div"); div.className = "three"; var box = document.querySelector(".box"); var one = document.querySelector(".one"); box.insertBefore(div, one); </script> </body>
结果:
案例 简单版发布留言案例
删除节点 node.removeChild(child)
从父节点 node 的子结点中删除指定子节点。,返回删除的节点。
1 2 3 4 5 6 7 8 9 10 11 <div class="box"> <div class="one"></div> <div class="two"></div> </div> <script> var box = document.querySelector(".box"); console.log(box.removeChild(box.children[0])); </script>
结果:
案例 删除留言案例
克隆节点 node.cloneNode()
返回调用该方法的节点的一个副本。
参数为空或者 false,则是浅拷贝,只克隆节点自身,不克隆里面的子节点,包括文本节点
参数为 true,则是深拷贝,克隆节点本身以及里面所有子节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 <div class="box"> 111 <div class="one">123</div> <div class="two">456</div> </div> <script> var box = document.querySelector(".box"); console.log(box.cloneNode()); console.log(box.cloneNode(true)); </script>
结果:
节点操作综合案例 动态生成表格案例
三种动态创建元素方法
document.write()
会导致页面全部重绘
例子:
1 2 3 4 5 6 7 8 9 10 11 <body> <button class="write">write方法</button> <script> let write = document.querySelector(".write"); write.onclick = () => { console.log(document.write("<h1>123</h1>")); } </script> </body>
点击前:
点击后:
2. element.innerHTML
例子:
1 2 3 4 5 6 7 8 9 <body> <div></div> <script> let div = document.querySelector("div"); div.innerHTML = "<h1>123</h1>"; </script> </body>
document.createElement()
只能根据参数的标签名创建对应元素节点,无内容,也无类名、id 等。
例子:
1 2 3 4 5 6 7 8 9 <div></div> <script> let div = document.querySelector("div"); let h1 = document.createElement("h1"); h1.innerHTML = "123"; div.appendChild(h1); </script>
效率测试:
innerHTML(拼接字符串)(1000 个 div)
1 2 3 4 5 6 7 8 9 const t1 = +new Date(); for (let j = 0; j < 1000; j++) { document.body.innerHTML += '<div></div>'; } const t2 = +new Date(); console.log(t2 - t1); //505ms
innerHTML(数组形式拼接)(10000 个 div)
1 2 3 4 5 6 7 8 9 10 11 const t1 = +new Date(); let arr = []; for (let j = 0; j < 10000; j++) { arr.push('<div></div>'); } document.body.innerHTML = arr.join(''); const t2 = +new Date(); console.log(t2 - t1); //15、14、13、11、9(ms)
createElement(10000 个 div)
1 2 3 4 5 6 7 8 9 10 11 const t1 = +new Date(); for (let j = 0; j < 10000; j++) { let div = document.createElement("div"); document.body.appendChild(div); } const t2 = +new Date(); console.log(t2 - t1); //14、16、19、13、11
innerHTML(数组形式拼接)的效率在测试中比 createElement 的稍微快一点,但只是一点点,一开始用 1000 个测试时,没办法分出区别,加大到 10000 个可以看出前者比后者稍快一点。
innerHTML(数组形式拼接)结构较复杂,需要另外用数组接,后面还得转成字符串,再塞给父节点。
createElement 结构较清晰,创建后直接使用 appendChild 就可以添加到父节点中。
学习链接:pink 老师前端入门