###写在前面
本来开开心心的看着ityped.js的源码,才看到几十行就发现怎么有两个方法没见过。然后翻看了一下MDN,发现自己的知识库要更新了。通过翻阅MDN和Stack Overflow,总结一些原生DOM操作的知识点,大致分为三个部分:Node解读、Element上的操作、DOM中的位置计算。
###Node的分类
Node中有很多类,但是有几个你必须记住:
| 类型 | nodeType |
| ----------- | -------- |
| 元素 Element | 1 |
| 属性 Attr | 2 |
| 文本 Text | 3 |
| 注释 Comment | 8 |
| 文档 Document | 9 |
###创建Node
创建一个元素节点
/**
* @param 元素的名称
*/
const el = document.createElement('div');
创建一个属性节点
/**
* @param 属性的名称
*/
const attr = document.createAttribute('title');
attr.value = "content";
创建一个文本节点
/**
* @param 文本内容
*/
const txt = document.createTextNode('i am student');
###nodeName属性
对于元素节点,返回的是元素的tagName
el.nodeName // DIV
对于属性节点,返回为属性的名称
attr.nodeName // title
对于文本节点,始终返回#text
txt.nodeName // #text
对于document节点, 始终返回#document
document.nodeName // #document
###nodeValue属性
对于元素节点和文档节点,返回的是null
el.nodeValue // null
document.nodeValue // null
对于文本节点,返回的就是文本的值
txt.nodeValue // i am student
对于属性节点,返回的就是属性的值
attr.nodeValue // content
###接下来用到的HTML结构
部分css
.one {
background-color: rgb(222,222,12);
display: none;
}
one
two
three
const demo = document.querySelector('.demo'),
one = document.querySelector('.one'),
two = document.querySelector('.two'),
three = document.querySelector('.three');
###子节点
if (demo.hasChildNodes()) {
demo.childNodes.forEach(function (item) {
console.log(item.nodeName);
})
}
输出:
#text
DIV
#text
DIV
#text
DIV
#text
这里特别要注意的是,为什么会出现四个#text,主要是我们的在写HTML标签时,换行符被解释成了文本节点。
/**
* 由上面的讲解,我们自然会知道下面输出什么
*/
console.log(demo.firstChild); // #text
console.log(demo.lastChild); // #text
但是我们在实际应用中,一般多是需要元素,所以有这两个方法:
console.log(demo.firstElementChild); //
console.log(demo.lastElementChild); //
###兄弟节点
console.log(demo.previousSibling); // #text
console.log(demo.nextSibling); // #text
同样你也可以用 previousElementSibling 和 nextElementSibling
###parentNode 与 parentElement
console.log(document.body.parentNode.nodeName); //HTML
console.log(document.body.parentElement.nodeName); //HTML
console.log(document.documentElement.parentNode); //#document
console.log(document.documentElement.parentElement); // null
###textContent 与 innerText
###添加节点
const newElement = document.createElement('div');
demo.appendChild(newElement);
/**
* 在目标节点之前插入一个节点
*/
const newElement1 = document.createElement('div');
one.parentNode.insertBefore(newElement1, one);
/**
* 原生的并未听过在一个节点的后面插入一个节点
* 可以DIY
*/
function insertAfter(newElement, target) {
if (target.nextElementSibling === null) {
target.parentNode.appendChild(newElement);
return;
}
target = target.nextElementSibling;
target.parentNode.insertBefore(newElement, target);
}
###复制节点
const copyElementDeep = demo.cloneNode(true); //带有子节点
const copyElement = demo.cloneNode(false); //不含子节点
###删除节点
/**
* 在调用parentNode.removeChild(node)之前
* 必须确保node是parentNode的子节点,否则会报错。
*/
if (demo.contains(newElement)) {
demo.removeChild(newElement);
}
###替换节点
###判断两个节点是否相等
const demo1 = document.createElement('div');
demo1.className = "some";
const demo2 = document.createElement('div');
demo2.className = 'some';
const demo3 = document.createElement('div');
demo3.className = "ok";
console.log(demo1.isEqualNode(demo1)); // true
console.log(demo1.isEqualNode(demo2)); // true
console.log(demo1.isEqualNode(demo3)); // false
console.log(demo1.isSameNode(demo1)); // true
console.log(demo1.isSameNode(demo2)); // false
console.log(demo1.isSameNode(demo3)); // false
const demo4 = demo1.cloneNode(true);
console.log(demo1.isSameNode(demo4)); // false
如果本文对您有帮助,欢迎关注微信公众号,为您推送更多大前端相关的内容, 欢迎留言讨论,ε=ε=ε=┏(゜ロ゜;)┛。
您还可以在这些地方找到我: