这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战。
前言
关于【SSD系列】:
前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。
先提问一波:(无框架前提下)
-
常用查询节点方法有哪些
-
什么是空白节点??她又到底是个什么东西
-
querySelectorAll 有哪些坑
-
怎么查询伪元素
-
四种删除节点方式你都知道吗
-
HTMLCollection 和 NodeList的区别
-
怎样删除所有的孩子节点
我们已经先jquery, vue, react等前端框架带来的便利了:
- jquery就不说了,一个
$
走天下,无限连。 - vue和react使用
ref
就能拿到对应节点。
离开了这些框架,你还能666的操作Node节点吗?
本文源码
crud-doms
节点查询
先放一段测试的html代码
<div class="outer" id="outer">
<ul class="list list-1">
<li class="item">list-one</li>
<li class="item">list-two</li>
<li class="item">list-three</li>
</ul>
</div>
<input type="button" name="btnSubmit" value="刷新"/>
常用的节点查询方法
-
getElementById
根据元素的
id
属性值进行节点查询,返回单一节点。document.getElementById("outer") // <div class="outer" id="outer">......
-
getElementsByClassName
根据元素的classname属性值就行查询。
document.getElementsByClassName("item") // HTMLCollection(3) [li.item, li.item, li.item]
-
getElementsByName
根源节点的name属性进行查询。
document.getElementsByName("btnSubmit") // NodeList [input]
-
getElementsByTagName
根据节点标签名进行查询。
document.getElementsByTagName("li") // HTMLCollection(3) [li.item, li.item, li.item]
-
querySelector
根绝css选择器进行节点查询,返回单个节点。
document.querySelector("#outer") // <div class="outer" id="outer">......
-
querySelectorAll
根绝css选择器进行节点查询,返回节点列表。
document.querySelectorAll(".item") // NodeList(3) [li.item, li.item, li.item]
在没有
querySelector
和querySelectorAll
出现之前,基本都是通过前四个查询方法配合childNodes
和parentNode
方法扩展出各种方法。
一些特殊查询属性
- document.all 返回所有的节点
- document.images 返回所有的图片
- document.forms 返回所有的form表单
- document.links 返回所有的链接标签
- document.embeds 返回所有的
object
标签元素,以前主要用于flash,pdf等等
querySelectorAll 注意事项
-
其返回的静态的
NodeList
, 随后对DOM
元素的改动不会影响其集合的内容。下面的代码可以看到,添加一个节后后, nodeList长度并没有变化。
<ul class="list list-1"> <li class="item">list-one</li> <li class="item">list-two</li> <li class="item">list-three</li> </ul> <script> var nodeList = document.querySelectorAll(".item"); console.log("len:", nodeList.length); // 3 var liEl = document.createElement("li"); liEl.className = "item"; liEl.innerHTML = "list-for" document.querySelector(".list").appendChild(liEl); console.log("len:", nodeList.length); //3 </script>
-
querySelectorAll可能返回的不是你期望的值
<div class="outer"> <div class="select"> <div class="inner"> </div> </div> </div> <script> var select = document.querySelector('.select'); var inner = select.querySelectorAll('.outer .inner'); inner.length; // 1, not 0! </script>
那么怎样才能返回期望的结果呢?答案是
:scope
var select = document.querySelector('.select'); var inner = select.querySelectorAll(':scope .outer .inner'); inner.length; // 0
-
转义特殊字符
<div id="foo\bar"></div> <div id="foo:bar"></div> <script> console.log('#foo\bar') // "#fooar" document.querySelector('#foo\bar') // 不匹配任何元素 console.log('#foo\\bar') // "#foo\bar" console.log('#foo\\\\bar') // "#foo\\bar" document.querySelector('#foo\\\\bar') // 匹配第一个div document.querySelector('#foo:bar') // 不匹配任何元素 document.querySelector('#foo\\:bar') // 匹配第二个div </script>
HTMLCollection 和 NodeList的区别
细心的通知可能发现了,上面的方法,有的返回的是HTMLCollection,有的返回的是NodeList。 他们有什么区别呢?
这里先要弄清晰继承关系:
HTMLElement -> Element -> Node-> EventTarget
EventTarget 前一个提供了事件分发能力,本身也是一个订阅发布中心,更多详情参见 3行代码一个订阅发布中心,不会不知道吧。
Node 有 12种节点类型,详情参见 NodeType,我们常用的 div, span等等属于nodeType=1的节点类型。
所以:
HTMLCollection 是元素节点类型,即nodeType为1的节点。
NodeList 是节点集合,包含文本节点,注释节点等等其他节点。
怎么查询伪元素
// html代码
<style>
.nihao::before{
content: '你好,';
}
</style>
<div class="nihao" id="nihao">
Tom
</div>
答案是不能,但你可以通过 window.getComputedStyle 来获取其样式。
window.getComputedStyle(nihao, "before")["content"] // "\"你好,\""
节点删除
先特出测试的html代码段
<ul class="list list-1">
<li class="item">list-one</li>
<li class="item">list-two</li>
<li class="item">list-three</li>
</ul>
Node.removeNode
这种我们用的最多的方法,前提是首先得获得要被删除元素的父节点,可以使用parentNode
或者parentElement
获得。
var ul = document.querySelector(".list");
console.log("li length", ul.children.length); // 3
ul.removeChild(ul.children[0]) // removeChild
console.log("li length", ul.children.length); // 2
Element.remove
这个方法属于 Element对象上,也就表明,其他nodeType类型是不可以使用的, 其不需要获得副节点。
var ul = document.querySelector(".list");
console.log("li length", ul.children.length); // 3
ul.children[0].remove(); // remove
console.log("li length", ul.children.length); // 2
outerHTML或者innerHTML
var ul = document.querySelector(".list");
console.log("li length", ul.children.length); // 3
ul.children[0].outerHTML = null // outerHTML
console.log("li length", ul.children.length); // 2
Document.adoptNode
从其他的document文档中获取一个节点。 该节点以及它的子树上的所有节点都会从原文档删除。
var ul = document.querySelector(".list");
console.log("li length", ul.children.length); // 3
document.adoptNode(ul.children[0]); // adoptNode
console.log("li length", ul.children.length); // 2
批量删除节点
批量删除,比如清除某个节点下的所有子节点,一般是使用while
循环,暴力的方式是 innerHTML = null
。
innerHTML = null
可能导致事件监听器没有被取消,以导致内存泄漏,具体有么有,还得看浏览器的实现。
我们封装一个吧:
function clearChildNodes(node){
while(node.hasChildNodes()){
node.removeChild(node.firstChild);
}
}
const ul = document.querySelector(".list");
console.log("nodes:", ul.childNodes.length); // 7
clearChildNodes(ul);
console.log("nodes:", ul.childNodes.length); // 0
空白节点
为什么是7个节点呢? 看图上的空白节点,有4个, 4+3 =7楼。
我们调整一下代码, 删除空白,再看输出
<ul class="list list-1"><li class="item">list-one</li><li class="item">list-two</li><li class="item">list-three</li></ul>
那空白节点,究竟是个什么东西??
看代码,其实就是nodeType为3的文本节点。进行输出的时候其textConent为空。
var ul = document.querySelector(".list");
console.log("li length", ul.childNodes.length); // 7
var firstNode = ul.childNodes[0];
console.log("nodeType", firstNode.nodeType); // 3
console.log("content", firstNode.textContent); //
我们不妨添加一点内容, 你就能清晰的知道了, 其childNodes长度依旧是7,第一个文本节点的内容是 text content
<ul class="list list-1">text content
<li class="item">list-one</li>
<li class="item">list-two</li>
<li class="item">list-three</li>
</ul>
小结
是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。
篇幅优先,如果star超过 100, 再写一篇节点增加和更新的文章。
写在最后
写作不易,你的一赞一评就是我前行的最大动力。
技术交流群,请加微信 dirge-cloud。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!