案例只留下案例名称,需复习的话,下载素材,按名字搜索后可找到文件
通过上文可知获取元素可以来利用 DOM 提供的方法来获取元素,如 getElementById、querySelector 等方法,但是也可以利用节点关系来获取元素

利用 DOM 树可以把节点划分为不同的层级关系,如父子层级、兄弟层级
node.parentNode
//node.parentNode
var son = document.querySelector(".son");
console.log(son.parentNode);
返回包含指定节点的子节点的集合,包含元素节点、文本节点等
<div class="father">
<div class="son"></div>
</div>
<script>
var father = document.querySelector(".father");
console.log(father.childNodes);
</script>
结果:

这种方法要获取元素节点,可以遍历所有节点,利用元素节点的 nodeType 为 1 的性质选出来。但是很麻烦。 2. parentNode.children
返回包含指定节点的子元素节点的集合,只返回元素节点
<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]获取最后一个子元素节点
新浪下拉菜单
两种方式,分别是所有的节点和元素节点。和获取子节点相似。
返回下一个兄弟节点,包含所有的节点。 2. node.previousSibling
返回下一个兄弟节点,包含所有的节点。 3. node.nextElementSibling
返回下一个兄弟元素节点 4. node.previousElementSibling
返回下一个兄弟元素节点
其中,3、4 有兼容性问题,IE9 以上才支持,可以封装兼容性函数
document.createElement(‘tagName’) 创建的元素原本不存在,是动态生成的,又被称为动态创建元素节点
var div = document.createElement("div");
创建节点后,创建的节点并不会出现,而需要把节点添加上去才可以。添加节点主要是先找到要添加的位置的父节点,然后才添加进去。有两种方法
将节点 child 添加到指定的父节点 node 的子节点末尾。
<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 的指定子节点前面
<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 的子结点中删除指定子节点。,返回删除的节点。
<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()
返回调用该方法的节点的一个副本。
<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>
结果:

动态生成表格案例
会导致页面全部重绘
例子:
<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
例子:
<body>
<div></div>
<script>
let div = document.querySelector("div");
div.innerHTML = "<h1>123</h1>";
</script>
</body>
只能根据参数的标签名创建对应元素节点,无内容,也无类名、id 等。
例子:
<div></div>
<script>
let div = document.querySelector("div");
let h1 = document.createElement("h1");
h1.innerHTML = "123";
div.appendChild(h1);
</script>效率测试:
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
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)
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 老师前端入门