JavaScript DOM查询,原生js实现元素子节点的获取
<p><span style="font-size: 18px"> 每个网页都是一个dom树,网页中所有的内容都是这个树上的一个节点。JavaScript的工作就是操作这些节点,对节点进行查增删改操作,或是给节点绑定事件。</span></p><p><img src="https://img2020.cnblogs.com/blog/1674722/202006/1674722-20200607194748969-1230346600.png"></p>
<p> 网页</p>
<p><img src="https://img2020.cnblogs.com/blog/1674722/202006/1674722-20200607202127714-596671787.png"></p>
<p> dom树</p>
<p><span style="font-size: 18px">要操作dom节点,首先要获取到dom节点。这里我介绍几个原生js获取元素子节点的方法:</span></p>
<p><strong style="font-size: 18pt"><strong>一、通过标签的属性值获取后代节点</strong></strong> </p>
<p><span style="font-size: 18px">以getElementBy开头的方法,可以根据具体的属性获取元素的后代节点。</span><span style="font-size: 18px">这些方法不只会获取子节点,他也会获取到所有符合条件的后代节点。</span></p>
<table border="0">
<tbody>
<tr>
<td>方法</td>
<td>依据属性</td>
<td>兼容性</td>
<td>其他</td>
</tr>
<tr>
<td>getElementById</td>
<td>id</td>
<td>
<p>兼容性好,推荐使用</p>
</td>
<td>
<p>如果存在多个id相同的元素,只会返回第一个</p>
</td>
</tr>
<tr>
<td>getElementsByTagName</td>
<td>标签名</td>
<td>不兼容ie8及以下版本</td>
<td> 返回所有符合条件的元素的集合</td>
</tr>
<tr>
<td>getElementsByName</td>
<td>name</td>
<td>不兼容ie8及以下版本</td>
<td> 返回所有符合条件的元素的集合</td>
</tr>
<tr>
<td>getElementsByClassName</td>
<td>class</td>
<td>不兼容ie8及以下版本</td>
<td>返回所有符合条件的元素的集合</td>
</tr>
</tbody>
</table>
<p><span style="font-size: 18px"> 以getElementById为例,尽管有两个id为’Jan‘的元素,但是只会获取到第一个:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">='Jan' </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">='test'</span><span style="color: rgba(0, 0, 255, 1)">></span>1<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">='Jan' </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">='test'</span><span style="color: rgba(0, 0, 255, 1)">></span>2<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">='Mar'</span><span style="color: rgba(0, 0, 255, 1)">></span>3<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> j</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">document.getElementById(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">Jan</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
console.log(j);
</span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p><span style="font-size: 18px">需要注意的是,<strong>在同一个文件中出现重复id是不符合规范的</strong>,应当尽量避免这样使用。</span></p>
<p><span style="font-size: 18px">如果将上面代码中的getElementById('Jan')换成 getElementsByTagName('p')或者是getElementsByClassName('test')将会获取到符合条件的结果集。</span></p>
<p> </p>
<p><span style="font-size: 18pt"><strong>二、child属性</strong></span></p>
<p><span style="font-size: 18px">每个dom元素都是一个对象,在dom元素对象中有四个专门用于获取子元素的属性:</span></p>
<table border="0">
<tbody>
<tr>
<td>属性名</td>
<td>作用</td>
<td>其他</td>
</tr>
<tr>
<td>childNodes</td>
<td>获取所有子节点</td>
<td>不推荐使用,如果有空格,会作为文本节点获取到</td>
</tr>
<tr>
<td>child</td>
<td>获取所有子节点</td>
<td>推荐使用</td>
</tr>
<tr>
<td>firstChild</td>
<td>获取首个子节点</td>
<td>推荐使用</td>
</tr>
<tr>
<td>lastChild</td>
<td>获取最后一个子节点</td>
<td>推荐使用</td>
</tr>
</tbody>
</table>
<p><span style="font-size: 18px">这四个属性都不存在兼容性问题,除了childNodes之外都是比较好用的。</span></p>
<p><span style="font-size: 18px">1. childNodes</span></p>
<p><span style="font-size: 18px">childNodes属性可以获取元素的所有子节点,并封装到一个数组中,可以通过下标来获取某个子元素:</span></p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="test"</span><span style="color: rgba(255, 0, 0, 1)"> id</span><span style="color: rgba(0, 0, 255, 1)">="test"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>1<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>3<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>5<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> a </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.getElementById(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">test</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
console.log(a.childNodes);
</span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p><span style="font-size: 18px">但是childNodes属性有一个问题,class=‘test’的div中只有3子节点,执行结果却有7个节点:</span></p>
<p><img src="https://img2018.cnblogs.com/blog/1674722/201905/1674722-20190515133154805-79139730.png"></p>
<p><span style="font-size: 18px">因为根据在网页中<strong>,标签之间的回车空格等特殊字符属于一个p元素</strong>,上面的div中输入了4个回车,因此会多出四个text节点:</span></p>
<p> <img src="https://img2018.cnblogs.com/blog/1674722/201905/1674722-20190515134007279-577426391.png"></p>
<p><span style="font-size: 18px">要解决这个问题有两个方法:</span></p>
<p><span style="font-size: 18px">方法一:去掉所有的回车空格等特殊字符,但是会影响程序的可读性和代码的规范。</span></p>
<p><span style="font-size: 18px">方法二:动态过滤掉空白字符:</span></p>
<p><span style="font-size: 18px">通过for循环遍历对象中的所有元素,删除纯文本元素。</span></p>
<p><span style="font-size: 18px">完整的代码就是这样:</span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> a = document.getElementById(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> b =<span style="color: rgba(0, 0, 0, 1)"> a.childNodes;
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(i=<span style="color: rgba(128, 0, 128, 1)">0</span>;i<b.length;i++<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(b.nodeName == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#text</span><span style="color: rgba(128, 0, 0, 1)">"&& !/\s/.test(b.nodeValue)</span><span style="color: rgba(0, 0, 0, 1)">){
a.removeChild(b);
}
}</span></pre>
</div>
<p><span style="font-size: 18px">第二种方法每次查询之前,都要先执行一段过滤代码。这样会影响程序的执行效率,因此childNodes属性不建议使用。</span></p>
<p> </p>
<p><span style="font-size: 18px">2. children</span></p>
<p><span style="font-size: 18px">相比childNodes,children属性不会将空格作为文本节点获取。因此就不需要额外的去除空格操作,获取节点的方式和chlidNodes属性相同。</span></p>
<p><span style="font-size: 18px">还是用上面的代码,将 </span><span style="font-size: 18px">a.childNodes 修改为 a.child 之后,会获取到三个p元素,这就是通常希望得到的结果。</span></p>
<p> </p>
<p><span style="font-size: 18px">chilren和childNodes属性存在的缺点是会获取全部的子节点,某些情况下使用时需要筛选,不够灵活。</span></p>
<p> </p>
<p><span style="font-size: 18px">3. firstChild&lastChild</span></p>
<p><span style="font-size: 18px">firstChild会获取首个子节点,相当于children的效果。</span></p>
<p><span style="font-size: 18px">lastChild会获取最后一个子节点,相当于children</span></p>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong><span style="font-family: 宋体; font-size: 18pt; background-color: rgba(255, 255, 255, 1)"><span style="color: rgba(51, 51, 0, 1)">三、</span></span><span style="font-family: 宋体; font-size: 18pt; background-color: rgba(255, 255, 255, 1)">querySelector方法,强烈推荐!</span></strong></span></p>
<p><span style="font-size: 18px">querySelector的参数是css选择器,任何选择器都可以作为它的参数,这样就使得它非常方便灵活:</span></p>
<p><span style="font-size: 18px">比如获取class=‘test’的标签下的第一个子元素,可以这样写</span><span style="font-size: 18px">querySelector('.test > * '),也可以指定子元素的类型querySelector('.test > span '),或者是:classquerySelector('.test > #</span>f_div<span style="font-size: 18px">')</span></p>
<p><span style="font-size: 18px">还可以使用querySelectorAll方法,这样会获取所有满足条件的元素,而不只是获取第一个元素。</span></p>
<p> </p>
<div class="cnblogs_code">
<pre><div class="first">
<span>张三</span>
</div>
<div id="second">
<div id=f_div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<script>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过类选择器获取节点</span>
doucument.querySelector('.first'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过id选择器获取节点</span>
doucument.querySelector('#second'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过伪类选择器获取子节点</span>
document.querySelector('.first>span'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//确认selectAll</span><span style="color: rgba(0, 128, 0, 1)">批量获取节点</span>
document.querySelectorAll('#second>div'<span style="color: rgba(0, 0, 0, 1)">);
</span></script></pre>
</div>
<p><span style="font-size: 18px">总体来说,我比较推荐使用querySelector方法,因为它更加灵活,使用作为css选择器进行选择非常方便。当然querySelector方法不只可以获取元素的子节点,它可以获取任何节点。querySelector方法可以兼容到IE8,基本能满足前端开发兼容性的需要。</span></p><br><br>
来源:https://www.cnblogs.com/iszhangk/p/10869009.html
頁:
[1]