2.03.09 节点相关属性与操作方法
1.节点的文本操作
nodeValue
仅在文本节点操作时该属性可以用来更新文本节点 用法:
<p id="demo">修改我的内容</p>
<script>
var x=document.getElementById("demo");
// 获取文本节点并修改
x.childNodes[0].nodeValue = "change";
</script>
innerHTML
属性设置或获取HTML语法表示的元素的后代。 元素对象.innerHTML,用于替换元素对象里的内容, 设置元素的 innerHTML将会删除所有该元素的后代并以上面给出的字符串替代。 用法:
<p id="myid">00000</p>
<div class="demo">a</div>
<div class="demo">b</div>
<div class="demo2" id="demo2">
bbbb
<div class="demo2_1">c</div>
</div>
<script>
var p=document.querySelector("p");
console.log(p.innerHTML); //00000
var div=document.querySelector("div");
div.innerHTML="<h1>HHHH111</h1>";// 会解析html代码,会在只会在这个div中标签中添加一个H1标签
var h1=div.innerHTML;
console.log(h1); //<h1>HHHH111</h1>
console.log(typeof h1);//string
</script>
注意:
如果一个 div, span节点有一个文本子节点,该节点包含字符 &, <, 或 >, innerHTML 将这些字符分别返回为 & , < 和 > 使用 textContent 可获取一个这些文本节点内容的正确副本。 设置元素的 innerHTML 将会删除所有该元素的后代并以上面给出的 htmlString 替代。
textContent
返回一个节点及其后代的文本内容,textContent 的值取决于具体情况:
如果节点是一个 document,或者一个 DOCTYPE ,则 textContent 返回 null。 如果节点是个 注释、文本节点,textContent 返回节点内部的文本内容,例如 Node.nodeValue。 对于元素节点类型,textContent 将所有子节点的 textContent 合并后返回 用法:
<p id="myid">00000</p>
<div class="demo">a</div>
<div class="demo">b</div>
<div class="demo2" id="demo2">
bbbb
<div class="demo2_1">c</div>
</div>
var p=document.querySelector("p");
var div = document.querySelector(".demo2");
console.log(p.textContent); //00000
console.log(div.textContent);
/*
控制台打印:
bbbb
c
*/
注意:textContent 与 innerHTML 的区别:
Element.innerHTML 返回 HTML。通常,为了在元素中检索或写入文本,人们使用 innerHTML。但是,textContent 通常具有更好的性能,因为文本不会被解析为HTML。 使用 textContent 可以防止 XSS 攻击
<div id="divA">This is <span>some</span> text!</div>
<script>
// 你可以使用 textContent 去获取该元素的文本内容
var text = document.getElementById('divA').textContent;
// 'This is some text!'
// 或者设置元素的文字内容:
document.getElementById('divA').textContent = 'This text is different!';
// <div id="divA">This text is different!</div>
</script>
innerText
该属性表示一个节点及其后代的“渲染”文本内容 注意:请避免使用该方法,因为他不会返回任何一个被css隐藏了的标签。(并且因为要判断元素是否渲染导致该api很消耗性能)
<p id="myid">00000</p>
<div class="demo">a</div>
<div class="demo">b</div>
<div class="demo2" id="demo2">
bbbb
<div class="demo2_1">c</div>
</div>
<script>
var p=document.querySelector("p");
console.log(p.innerHTML); //00000
console.log(p.innerText); //00000
var div=document.querySelector(".demo2");
console.log(div.innerHTML);
//控制台打印:
//bbbb
//<div class="demo2_1">c</div>
console.log(div.innerText);
//控制台打印:
//bbbb
//c
</script>
textContent 与 innerText 的区别:
textContent 会获取所有元素的内容,包括 script 和 style 元素,然而 innerText 只展示给人看的元素。 textContent 会返回节点中的每一个元素。相反,innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本, 与 textContent 不同的是, 在 Internet Explorer (小于和等于 11 的版本) 中对 innerText 进行修改, 不仅会移除当前元素的子节点,而且还会永久性地破坏所有后代文本节点。在之后不可能再次将节点再次插入到任何其他元素或同一元素中。
<h3>Source element:</h3>
<p id="source">
<style>#source { color: red; }</style>
Take a look at<br>how this text<br>is interpreted
below.
<span style="display:none">HIDDEN TEXT</span>
</p>
<h3>Result of textContent:</h3>
<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
<h3>Result of innerText:</h3>
<textarea id="innerTextOutput" rows="6" cols="30" readonly>...</textarea>
<script>
var source = document.getElementById('source');
var textContentOutput = document.getElementById('textContentOutput');
var innerTextOutput = document.getElementById('innerTextOutput');
textContentOutput.innerHTML = source.textContent;
innerTextOutput.innerHTML = source.innerText;
2.元素节点的属性相关操作
getAttributeNode()
// html: <div id="top"></div>
var t = document.getElementById("top");
var idAttr = t.getAttributeNode("id");
alert(idAttr.value == "top")//true
//idAttr是一个对象,一个节点
//idAttr.value才是一个属性名称,一个字符串
var idAttr = t.getAttributeNode("ID");
alert(idAttr.value == "top")/true
idAttr = t.getAttributeNode("name");
console.log(idAttr); //null
注意:
当在一个被标记为HTML文档的DOM中的HTML元素上调用这个方法时, getAttributeNode会将参数转变为小写形式。 属性节点继承自Node,但不被认为是文档树的一部分。Node上定义的常用属性,如 parentNode, previousSibling, 和 nextSibling 对于属性节点来说都为null。
hasAttribute()
返回一个布尔值,指示该元素是否包含有指定的属性(attribute)。 用法:
// 在为属性设置新值前检测该属性是否存在
var d = document.getElementById("div1");
if (d.hasAttribute("align")) {
d.setAttribute("align", "center");
}
getAttribute()
返回元素上一个指定的属性值。如果指定的属性不存在,则返回 null 或 “” (空字符串) 用法:
HTML:
<img src="./images/2020.jpg" alt="" class="pic">
js:
// 获取img标签
var img = document.querySelector(".pic");
// 获取img标签src属性值
var v = img.getAttribute("src");
console.log(v); //src
注意:getAttribute 通常用于替换getAttributeNode方法,来获得元素的属性值。性能也更快. 性能对比是 element.id 大于 element.getAttribute(‘id’) 大于 element.getAttributeNode(‘id’).nodeValue。
setAttribute()
设置指定元素上的某个属性值。如果属性已经存在,则更新该值;否则,使用指定的名称和值添加一个新的属性。 注意:
当在 HTML 文档中的 HTML 元素上调用 setAttribute() 方法时,该方法会将其属性名称(attribute name)参数小写化。如果指定的属性已经存在,则其值变为传递的值。如果不存在,则创建指定的属性。 布尔属性只要出现在元素上就会被认为是 true ,无论它的值是什么; 要设置布尔属性的值(例如禁用),可以指定任何值。 建议使用空字符串或属性名称。 重要的是,如果根本不存在该属性,则不管其实际值如何,都将其值视为真实。 该属性的缺失表示其值是false。 由于布尔属性只要出现在元素上就会被认为是 true 或者 setAttribute会将指定的值转换为字符串,因此指定null不一定能达到我们的期望。 导致无法删除属性或将其值设置为null,而是将属性的值设置为字符串“null”。
HTML:
<img src="./images/2020.jpg" alt="" class="pic">
js:
var img = document.querySelector(".pic");
// 设置img标签src属性
img.setAttribute("src", "./images/2021.jpg");
var v = img.getAttribute("src");
console.log(v); //./images/2021.jpg
removeAttribute()
HTML:
<img src="./images/2020.jpg" alt="" class="pic">
js:
var img = document.querySelector(".pic");
// 删除img的src属性
img.removeAttribute("src");
var v = img.getAttribute("src");
console.log(v); //null
3.创增删插节点
createElement()
方法用于创建一个由标签名称 tagName 指定的 HTML 元素并返回。 用法:
<script>
// 创建一个新的 div 元素
var newDiv = document.createElement("div");
console.log(newDiv) //<div></div>
</script>
appendChild()
方法将一个节点附加到指定父节点的子节点列表的末尾处。如果将被插入的节点已经存在于当前文档的文档树中,那么 appendChild() 只会将它从原先的位置移动到新的位置(不需要事先移除要移动的节点)。 用法:
<div id="div1">这里的文本是动态创建的。</div>
<script>
// 创建一个新的 div 元素
var newDiv = document.createElement("div");
newDiv.textContent = '设置一段文本';
// 将这个新的元素和它的文本添加到 DOM 中
var currentDiv = document.getElementById("div1");
currentDiv.appendChild(newDiv);
</script>
removeChild() 与 remove()
removeChild() 调用者是父元素
方法从DOM中删除一个子节点。返回删除的节点。 注意:被移除的这个子节点仍然存在于内存中,只是没有添加到当前文档的DOM树中,因此,你还可以把这个节点重新添加回文档中。但是若要实现此功能需要用另外一个变量比如上例中的oldChild来保存这个节点的引用。 如果没有使用变量, 即没有使用 oldChild 来保存对这个节点的引用, 则认为被移除的节点已经是无用的, 在短时间内将会被内存管理回收。 remove() 调用者是本身
用法:
<div id="container">
<ul>aaa</ul>
</div>
<script>
var div=document.querySelector("#container");
var ul=document.querySelector("ul");
//var a = div.removeChild(ul);
console.log(a); //<ul>aaa</ul>
var b= ul.remove();
console.log(b); //undefined
</script>
insertBefore()
在指定元素之前插入元素 调用者是父元素,第一个参数是待插入的元素,第二个参数是指定的元素 用法:
<div id="container">
<ul>aaa</ul>
</div>
<script>
var div=document.querySelector("#container");
var ul=document.querySelector("ul");
var h1=document.createElement("h1");
h1.innerText="待插入的h1";
div.insertBefore(h1,ul);
createTextNode()
创建一个新的文本节点。这个方法可以用来转义 HTML 字符。 用法:
// 创建一个新的 div 元素
var newDiv = document.createElement("div");
// 动态创建文本节点
var newContent = document.createTextNode("被创建的文本节点");
// 添加文本节点 到这个新的 div 元素
newDiv.appendChild(newContent);
// 将这个新的元素和它的文本添加到 DOM 中
var currentDiv = document.getElementById("div1");
currentDiv.appendChild(newDiv);
4.通过节点间的关系获取节点
1.没排空功能的
previousSibling
返回当前节点的前一个兄弟节点,没有则返回null. 用法:
<div id="div1"></div><div id="div2"></div>
<script>
var div2=document.querySelector("#div2");
console.log(div2.previousSibling);//<div id="div1"></div>
</script>
注意:Gecko内核的浏览器会在源代码中标签内部有空白符的地方插入一个文本结点到文档中。因此,使用诸如 Node.firstChild、 Node.previousSibling、Node.nextSibling、Node.lastChild之类的方法可能会引用到一个空白符文本节点, 而不是使用者所预期得到的节点。
nextSibling
返回前节点紧跟在其后面的兄弟节点,如果指定的节点为最后一个节点,则返回 null。 用法:
<div id="div1"></div>
<div id="div2"></div>
<script>
var div1=document.querySelector("#div1");
console.log(div1.nextSibling);//#text
console.log(div1.nextSibling.nextSibling);//<div id="div2"></div>
</script>
firstChild
返回当前节点的第一个子节点,如果节点是无子节点,则返回 null。 用法:
<p id="para-01">
<span>First span</span>
</p>
<script type="text/javascript">
var p01 = document.getElementById('para-01');
alert(p01.firstChild.nodeName)//#text
</script>
<p id="para-02"><span>First span</span></p>
<script type="text/javascript">
var p02 = document.getElementById('para-02');
alert(p02.firstChild.nodeName) // 'SPAN'
</script>
lastChild
返回当前节点的最后一个子节点。如果父节点为一个元素节点,则子节点通常为一个元素节点,或一个文本节点,或一个注释节点。如果没有子节点,则返回 null。 用法:
<p id="para-02"><span>First span</span></p>
<script type="text/javascript">
var p02 = document.getElementById('para-02');
alert(p02.lastChild.nodeName) // 'SPAN'
</script>
2.空白节点
空白节点
介绍:绝大多数浏览器,都会把元素之间的空白当做文本节点来处理,所以上面四个属性可能会返回空白元素即空白节点。DOM 中的空白符会让处理节点结构时增加不少麻烦导致:
有些空白符会自成一个文本节点。 有些空白符会与其他文本节点合成为一个文本节点。
排除空白节点
function getPrevElement(text){
var prev = text.previousSibling;
// element.nodeType == 1 是一个非空白节点
while (prev.nodeType !=1) {
console.log(prev);
prev = prev.previousSibling;
}
return prev;
}
除此以外JavaScript还提供了四个属性,解决上面四个属性获取空白节点的问题可以直接获取元素节点
3.有排空功能的
previousElementSibling
返回当前元素在其父元素的子元素节点中的前一个元素节点,如果该元素已经是第一个元素节点,则返回null。即,当前标签的上一个元素 用法:
<div id="div-01">Here is div-01</div>
<div id="div-02">Here is div-02</div>
<script>
var el = document.getElementById('div-02');
console.log(el.previousElementSibling);//<div id="div-01">Here is div-01</div>
</script>
nextElementSibling
返回当前元素在其父元素的子元素节点中的后一个元素节点,如果该元素已经是最后一个元素节点,则返回null。即,当前标签的下一个元素 用法:
<div id="div-01">Here is div-01</div>
<div id="div-02">Here is div-02</div>
<script>
var el = document.getElementById('div-01');
console.log(el.nextElementSibling);//<div id="div-02">Here is div-02</div>
</script>
firstElementChild
返回对象的第一个子 元素, 如果没有子元素,则为null。 用法:
<ul id="foo">
<li>First (1)</li>
<li>Second (2)</li>
<li>Third (3)</li>
</ul>
<script>
var foo = document.getElementById('foo');
//<li>First (1)</li>
console.log(foo.firstElementChild);
</script>
lastElementChild
返回对象的最后一个子元素,如果没有子元素,则返回 null。 用法:
<ul id="foo">
<li>First (1)</li>
<li>Second (2)</li>
<li>Third (3)</li>
</ul>
<script>
var foo = document.getElementById('foo');
//<li>First (3)</li>
console.log(foo.lastElementChild);
</script>
4.其他
parentElement 当前元素的父元素 childNodes 获取子节点(即,文本节点、标签节点等) parentElement 获取子元素
HTML:
<div></div>
<span></span>
<ul>
<li>
hello world
<div>加粗字体</div>
</li>
<li>2</li>
<li>3</li>
</ul>
JS:
var ul = document.getElementsByTagName("ul")[0];
var lis = ul.children;
var el = lis[0];
var el = lis[0];
var el2 = lis[1];
// 获取子节点(标签、文本、属性)
console.dir(el.childNodes); // NodeList(3)
console.dir(el2.childNodes);// NodeList(1)
console.dir(ul.childNodes);// NodeList(7)
console.dir(el.childNodes[0]);// 文本节点 nodeType == 3
console.dir(el.childNodes[1]);// 标签节点 nodeType == 1
console.dir(el.childNodes[2]);// 文本节点
// 获取ul标签下的第二个li标签
//var second_el = lis[1];
//console.log(second_el);// <li>2</li>
// 相邻关系,获取上一个元素
//var prev_el = second_el.previousElementSibling;
//console.log(prev_el);// <li>1</li>
// 相邻关系,获取下一个元素
//var next_el = second_el.nextElementSibling;
// console.log(next_el);// <li>3</li>
// 获取当前标签的父元素
//var parent_el = second_el.parentElement;
//console.log(parent_el);// ul标签