1、DOM 节点简介
DOM 1 级定义了 Node 接口,该接口为 DOM 的所有节点类型定义了原始类型。JavaScript 实现了这个接口,定义所有节点类型必须继承 Node 类型。作为 Node 的子类或孙类,都拥有 Node 的基本属性和方法。
DOM 规定:整个文档是一个文档节点,每个标签是一个元素节点,元素包含的文本是文本节点,元素的属性是一个属性节点,注释属于注释节点,如此等等。每个节点都有一个 nodeType 属性,用于表明节点的类型。如:
<div id="div"></div> <script> let div = document.getElementById('div'); console.log(div.nodeType); // 1 </script>
数字 1 表示元素 Element,也叫标签 Tag。数字 3 表示文本 Text,数字 8 表示注释 Comment,数字 9 表示文档 Document。
2、创建一个dom节点(增)
createElement() 方法能够根据参数指定的标签名称创建一个新的元素,并返回新建元素的引用,createTextNode() 方法能创建一个文本节点,具体步骤如下所示:
//element表示新建元素的引用,createElement()是document对象的一个方法,该方法只有一个参数,用来指定创建元素的标签名称 let element = document.createElement("tagName"); //创建一个标签节点 let div = document.createElement('div'); console.log("nodeName:" + div.nodeName + ",noderype:" + div.nodeType); let style = document.createElement('style'); //创建一个文本节点 let text = document.createTextNode('你好');
使用 createElement() 方法创建的新元素默认处于JS线程中,不会被自动添加到文档里,因为新元素还没有 nodeParent 属性,仅在 JavaScript 上下文中有效,必须把它插到 head 或者 body 里面,它才会生效。可以通过使用 appendChild()、insertBefore() 或 replaceChild() 方法实现,将新创建的元素添加到 head 或 body 中;document.body.appendChild(div)或者,已在页面中的元素.appendChild(div)。
let p = document.createElement("p"); //创建段落元素 document.body.appendChild(p); //增加段落元素到body元素下 let div = document.createElement('div'); let text = document.createTextNode('你好'); div.appendChild(text); //上述三步可以简化 let div = document.createElement('div'); div.innerText = '你好'; //或者 div.textContent = '你好';,但是不能用 div.appendChild('你好')
3、克隆一个dom节点(增)
cloneNode() 方法可以创建一个节点的副本,其用法:
nodeObject.clone(include_all); //参数 include_all 为布尔值,如果为 true,那么将会克降原节点,以及所有子节点:为 false 时,仅复制节点本身。
和 createElement() 方法一样,clone 复制后返回的节点副本属于文档所有,但并没有为它指定父节点,需要通过 apendChild() 、insertBefore() 或 replaceChild() 方法将它添加到文档中。
var p = document.createElement("p"); //创建一个p元素 var h1 = document.createElement("hl"); //创建一个h1元素 var txt = document.createTextNode("Hello World"); //创建一个文本节点 var hello = txt.cloneNode(false); //复制创建的文本节点 p.appendChild(txt); //把复制的文本节点增加到段落节点中 h1.appendChild(p); //把段落节点增加到标题中 document.body.appendchild(h1); //把标题节点增加到body节点中 var new_h1 = h1.cloneNode(true); //复制标题元素及其所有子节点 document.body.appendchild(new_h1); //把复制的新标题元素增加到文档中
由于 clone 复制的节点会包含节点的所有特性,如果原节点中包含 id 属性,就会出现 id 属性值重叠情况。一般情况下,在同一个文档中,不同元素的 id 属性值应该不同,为了避免潜在冲突,应修改其中某个节点的 id 属性值。
4、删除一个dom节点(删)
parentNode.removeChild(node),removeChild() 方法可以从节点列表中删除某个子节点,其中参数 node 为要删除的节点。如果删除成功,则返回被删除的节点;如果失败,则返回 null。当使用 removeChild() 方法删除节点时,该节点所包含的所有子节点将同时被删除。
let div = document.getElementById('div'); div.parentNode.removeChild('div'); //改div元素依然存在内存中 document.body.appendChild('div'); //依然可以将div再添加回来,可以将div赋值为null将其删除掉
这种 removeChild() 方法需要先找到要删除元素的父节点,这不免有些麻烦,来看一下 remove() 方法:
let div = document.getElementById('div'); div.remove(); //改div元素依然存在内存中 document.body.appendChild('div'); //依然可以将div再添加回来,可以将div赋值为null将其删除掉
5、修改dom节点的相关属性(改)
(1)修改dom节点的属性:className 可添加类型,classList.add() 的方式添加class较为推荐。style 可修改元素的样式属性,或修改元素的单个样式属性,注意长单词的大小写,如:backgroundColor。setAttribute() 和 getAttribute() 方法可以设置和获取元素的指定属性。dataset 可修改元素的 data-* 属性。
let div = document.getElementById('div'); //修改class,因为class为关键字,所以要用className代替 div.className += ' green'; //通常用 += 来添加类型 div.className = 'red blue'; //会全覆盖之前的class类名 //可以通过classList.add()方法添加class类型 div.classList.add('red'); //div.classList可以读取元素的class列表 div.style = 'width:100px;color:blue;' //修改元素的style属性 div.style.width = '200px'; //改元素的单个style属性 div.style.backgroundColor = 'white'; //注意大小写,所有用中划线的属性在js中用大写代替 div.setAttribute('data-x','erha'); //setAttribute()的方式添加属性 div.getAttribute('data-x'); //erha div.dataset.x = 'erha'; //修改data-*自定义属性
注意:<a> 标签的 href 属性,如果通过 a.href 的方式获取,如果 href 的值是相对路径,浏览器会进行加工(添加当前网址),该属性最好通过 a.getAttribute('href');的方式来获取其原本的值。
(2)修改dom节点的内容,通过 innerText 或 textContent 属性可修改 dom 节点内的文本内容,innerHTML 属性可改 HTML 内容
let div = document.getElementById('div'); //修改文本内容 div.innerText = 'xxx'; div.textContent = 'xxx'; //两者几乎没有区别 //改HTML内容 div.innerHTML = '<strong>重要内容</strong>'; //改标签 div.innerHTML = ''; //先清空 div.appendChild(div1); //再加内容 //修改div节点的父元素 newParent.appendChild(div); //div直接从原来的地方消失,到了newParent节点
6、查看dom节点的相关属性(查)
获取当前节点后,可以通过 parentNode、childNodes、firstChild 等属性查看当前节点的相关节点:
let node = document.getElementById('div'); //查看当前节点的父节点 node.parentNode; // 或者node.parentElement //查看当前节点的祖先节点 node.parentNode.parentNode; //查看当前节点的孩子节点 node.childNodes; // 或者node.children childNodes会将回车空格看作一个结点,后者不会 //查看当前节点的兄弟节点 node.parentNode.childNodes; // 或者node.parentNode.children 但是还要排除自己(遍历) //查看当前节点的第一个或最后一个孩子节点老大 node.firstChild; //或者通过node.children[0] node.lastChild; //查看当前节点的上一个或下一个兄弟节点 node.previousSibling; node.nextSibling;