选取文档元素的API
除了現在常用的選取API 1 document.getElementById() 2 document.getElementsByName() 3 document.getElementsByTagName() 4 ...
?新增的API 主要是
document.querySelector('div>ul')
document.querySelectorAll('div>ul>li')
? ? ?這兩個API的強大之處在于能像CSS選擇器一樣選擇元素,和Jquery的選擇器有的一拼
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<ul>
<li></li>
<li class="abc"></li>
<li class="bbb abc"></li>
</ul>
</div>
<div>
<p>11111111111111
</p>
</div>
</body>
<script>
var a=document.querySelectorAll('div>ul')[0]
console.log(a.childElementCount) // 3
var b=document.createElement('li');
b.textContent='44444';
a.appendChild(b) console.log(a.childElementCount) //3
console.log(document.querySelectorAll('div>ul>li').length) //4 </script>
</html>
以下介紹下他們的不同點:
? ? document.querySelector()
? ? ? ? 返回的是第一個匹配的元素(以文檔順序)
? ? ? ? 匹配不到則返回null
? ?document.querySelectorAll()
? ? ? ?返回的是一個表示文檔中匹配選擇器的所有元素的NodeList對象(顯然該對象是一個集合),
? ? ? ?這個NodeList對象并不是實時的:它包含在調用時刻選擇器鎖匹配的元素,但并不更新后續文檔的變化(詳見上面實列)
? ? ? ?匹配不到則返回一個空的NodeList對象
? ? ? 選擇器非法 將拋出異常
另外一點是這兩個方法在Element節點中也有定義 (DocumentFragment節點上也是有定義的)
如:
? ? ?var d=document.getElementsByTagName('div')[0].querySelector('.abc')
? ? ?console.log(d.textContent)
目前支持這兩個API 有:IE8+,Firefox 3.5+,Safari 3.1+,Chrom 和Opera 10+
有一個小問題:
? ? <div id="abcdefg">
? ? ? ? ? ? ? ? <p>11111111111111
? ? ? ? ? ? ? ?</p>
? ? </div>
? ? ?var c=document.querySelector('#abcdefg');
? ? ?console.log(c.querySelector('div p').innerHTML); // 這個是能找到值的
? ?理想情況是 在id為abcdefg 的內部查找 div 下面的p元素,顯示出p的innerHTML 應該是找不到的
? ?但是現在卻打印出來了 It's a problem; 查詢時也必要這樣查詢
? ?應該一次性寫出來: document.querySelector('#abcdefg div p'); 會報異常 因為找不到
?
性能問題:
? ? ? ?通過對1千萬次的讀取發現getElementBy系列的查詢速度要遠高與 queryselector系列
?
1 var begin = new Date(); 2 for (var i = 0; i < 10000000; i++) { 3 4 var a=document.getElementById('abc'); 5 6 } 7 var end= new Date(); 8 console.log(end-begin); 9 var begin1 = new Date(); 10 for (var i = 0; i < 10000000; i++) { 11 12 var a=document.querySelector('#abc'); 13 14 } 15 var end1=new Date(); 16 console.log(end1-begin1);? ?究其原因發現 主要是因為queryselectorall ?返回的nodeList是靜態的 而getElementBy 系列返回的是動態的 ?細化一下主要是:
? ? ? ? ?在深入了解細節之前,首先說下這倆個方法重要的區別,不僅僅是一個方法接受tagName,另外一個接受css選擇器。最重要的區別在于返回值: getElementsByTagName() 返回一個實時的 NodeList,
querySelectorAll()返回靜態的 NodeList。 這點是對理解速度的快慢是非常重要的。實時的NodeList?這個是文檔對象模型(Document Object Model)的一個坑。 NodeList對象(也就是在HTML DOM中的HTMLCollection對象)是個特殊的類型。DOM3手冊對HTMLCollection對象的規定如下:
? ? ? ? Nodelist跟NamedNodeMap對象在DOM中是實時的;也就是說,對基本文檔結構的修改,會被映射到相關的Nodelist跟NameNodeMap對象。例如,如果一個DOM的用戶得到了包含有子元素節點的NodeList對象,隨后在這個元素上添加更多的子節點(或者是移除,或者是修改他們),這些改變會自動映射到NodeList對象中,不需要用戶部分的額外操作。同樣的,改變在樹中的節點,也會自動映射到跟這個節點有關的
NodeList跟NamedNodeMap中的對象。
getElementsByTagName()方法,返回這些實時的元素集合-隨著文檔的改變而更新。因此,下邊這段代碼其實是個死循環:
因為divs.lenght實時計算的原因,所以這是個死循環。每次迭代,添加一個新的div,意味著divs.length每次循環都會增加。
這些實時的集合,看起來像個壞主意,但是他們被放到document.images,document.forms這些方法中,跟其他的一些pre-DOM的集合中使用相同的對象,在瀏覽器中非常常見。
? 靜態的NodeList
? ? ? ? querySelectorAll()返回的是靜態的NodeList,描述如下:被querySelectorAll() 返回的對象必須(must)是靜態的,非實時的([DOM-LEVEL-3-CORE],1.1.1部分)。后來的對文檔的改變,不能(must not)反應到NodeList對象上。這意味著,此對象實際上包含的是文檔剛創建的時候,查詢到的匹配的列表。所以,即使querySelectorAll()的返回值跟表現,同getElementsByTagName()是一樣的,但是實際上,他們是不同的。在前者中,NodeList實際上是一個文檔狀態,在方法被調用時刻的快照,后者總是會更新到當前的狀態。所以,下邊的代碼不是死循環:
div.length 不會改變。
? ?So為啥是實時的NodeLists更快呢?
? ? ? ?實時的NodeLit對象能夠快速的被瀏覽器創建,并返回,因為他們他們不必知道從開始到現在的數據信息,但是,靜態的需要收集這些信息。再此強調下,WebKit的源碼對兩中類型的NodeList有獨立的文件:DynamicNodeList.css跟StaticNodeList.cspp.兩種類型的對象以不同的方式被創建。DynamicNodelist是被注冊到緩存中。本質上,創建DynamicNodelist開銷是比較小的,因為他不會之前的事情。無論何時DynamicNodeList被訪問的時候,它必須查詢文檔的改變,作為length屬性跟item()方法的結果跟StaticNodeList比較,在另外一個文件中實例被創建,然后用內部的一個循環,進行數據填充。之前文檔查詢的開銷比使用”DynamicNodeList”實例大的多。如果你看一下WebKit的源碼,創建querySelectorAll()的返回值的時候,都是使用循環去創建這個結果。
??結論:
? ? ?getElementsByTagName()比querySelectorAll()快的原因是,實時跟靜態NodeList對象引起的。
? ? ?決定使用哪個方法,主要取決于你想要什么。如果你通過tagName搜索元素,不需要快照,應該使用getElementsByTagName();如果你需要一個快照結果,或者是做一個更復雜的css查詢,應當使用
**querySelectorAll()*
? ? 注,部分文檔摘錄自:
http://www.cnblogs.com/dolphinX/p/3354318.html
?http://www.heyria.com/index.php/2014/06/why-is-getelementsbytagname-faster-that-queryselectorall/
?
?
? ? ?
轉載于:https://www.cnblogs.com/ArthurXml/p/5387637.html
總結
以上是生活随笔為你收集整理的选取文档元素的API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 今日工作小结
- 下一篇: 软件工程第一次冲刺进度条(1-10天)