日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

[label][转载][JavaSript]querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?

發布時間:2025/3/14 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [label][转载][JavaSript]querySelectorAll 方法相比 getElementsBy 系列方法有什么区别? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?轉載出處: http://www.zhihu.com/question/24702250

querySelectorAll?相比下面這些方法有什么區別?

    • getElementsByTagName
    • getElementsByClassName
    • getElementsByName

1. W3C 標準
querySelectorAll 屬于 W3C 中的 Selectors API 規范 [1]。而 getElementsBy 系列則屬于 W3C 的 DOM 規范 [2]。

2. 瀏覽器兼容
querySelectorAll 已被 IE 8+、FF 3.5+、Safari 3.1+、Chrome 和 Opera 10+ 良好支持 。
getElementsBy 系列,以最遲添加到規范中的 getElementsByClassName 為例,IE 9+、FF 3 +、Safari 3.1+、Chrome 和 Opera 9+ 都已經支持該方法了。

3. 接收參數
querySelectorAll 方法接收的參數是一個 CSS 選擇符。而 getElementsBy 系列接收的參數只能是單一的className、tagName 和 name。代碼如下 [3]:

var c1 = document.querySelectorAll('.b1 .c'); var c2 = document.getElementsByClassName('c'); var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');

需要注意的是,querySelectorAll 所接收的參數是必須嚴格符合 CSS 選擇符規范的。所以下面這種寫法,將會拋出異常。代碼如下 [4]:

try {var e1 = document.getElementsByClassName('1a2b3c'); var e2 = document.querySelectorAll('.1a2b3c'); } catch (e) { console.error(e.message); } console.log(e1 && e1[0].className); console.log(e2 && e2[0].className);

(CSS 選擇器中的元素名,類和 ID 均不能以數字為開頭。)

4. 返回值
大部分人都知道,querySelectorAll 返回的是一個 Static Node List,而 getElementsBy 系列的返回的是一個 Live Node List。
看看下面這個經典的例子 [5]:

// Demo 1 var ul = document.querySelectorAll('ul')[0], lis = ul.querySelectorAll("li"); for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li")); } // Demo 2 var ul = document.getElementsByTagName('ul')[0], lis = ul.getElementsByTagName("li"); for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li")); }

因為 Demo 2 中的 lis 是一個動態的 Node List, 每一次調用 lis 都會重新對文檔進行查詢,導致無限循環的問題。
而 Demo 1 中的 lis 是一個靜態的 Node List,是一個 li 集合的快照,對文檔的任何操作都不會對其產生影響。

但為什么要這樣設計呢?
其實,在 W3C 規范中對 querySelectorAll 方法有明確規定 [6]:

The NodeList object returned by the querySelectorAll() method?must be static?([DOM], section 8).


那什么是 NodeList 呢?
W3C 中是這樣說明的 [7]:

The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented.?NodeList objects in the DOM are live.

所以,NodeList 本質上是一個動態的 Node 集合,只是規范中對 querySelectorAll 有明確要求,規定其必須返回一個靜態的 NodeList 對象。

我們再看看在 Chrome 上面是個什么樣的情況:

document.querySelectorAll('a').toString(); // return "[object NodeList]" document.getElementsByTagName('a').toString(); // return "[object HTMLCollection]"

這里又多了一個 HTMLCollection 對象出來,那 HTMLCollection 又是什么?

HTMLCollection 在 W3C 的定義如下 [8]:

An HTMLCollection is a list of nodes. An individual node may be accessed by either ordinal index or the node's name or id attributes.
Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.


實際上,HTMLCollection 和 NodeList 十分相似,都是一個動態的元素集合,每次訪問都需要重新對文檔進行查詢。兩者的本質上差別在于,HTMLCollection 是屬于?Document Object Model HTML?規范,而 NodeList 屬于?Document Object Model Core?規范。
這樣說有點難理解,看看下面的例子會比較好理解 [9]:

var ul = document.getElementsByTagName('ul')[0], lis1 = ul.childNodes, lis2 = ul.children; console.log(lis1.toString(), lis1.length); // "[object NodeList]" 11 console.log(lis2.toString(), lis2.length); // "[object HTMLCollection]" 4

NodeList 對象會包含文檔中的所有節點,如 Element、Text 和 Comment 等。
HTMLCollection 對象只會包含文檔中的 Element 節點。
另外,HTMLCollection 對象比 NodeList 對象 多提供了一個 namedItem 方法。

所以在現代瀏覽器中,querySelectorAll 的返回值是一個靜態的 NodeList 對象,而 getElementsBy 系列的返回值實際上是一個 HTMLCollection 對象 。



[1]?Selectors API Level 2
[2]?Document Object Model Core
[3]?
[4]?
[5]?
Demo 1:?
Demo 2:?
[6]?Selectors API Level 2
[7]?Document Object Model Core
[8]?Document Object Model HTML
[9]?

?
getElementById / querySelector 這兩個獲取到的都是dom節點,結果沒有區別。

getElement* 的實時性體現在返回集合的時候,我們知道getElementsBy*和querySelectorAll返回的都是一個節點集合,類似于數組,兩種方法的區別就在于這個集合會不會自動更新。

//初始時DOMain中沒有<img>元素 x = document.querySelectorAll('img') y = document.getElementsByTagName('img') document.body.appendChild(new Image()) x.length // 0 y.length // 1


另外,getElementById這個只能用在document上,因為正常情況下id是唯一的。

?

上面說了很多querySelectorAllgetElementsBy實現和原理上面的區別,我這里拿數據說話,看看兩者在性能上的區別。

所有測試來源于,有興趣的朋友可以自己去試試。

  • 硬件環境: Core i5-3570 3.40GHz, Win7 64bit



  • 數據格式:[ Ops/Sec] method

Ops/Sec是指每秒執行操作的次數,越高越好。

  • 瀏覽器1: Chrome 37.0.2062.68 32-bit
[-20,989,532] document.getElementsByTagName('a'); [----166,170] document.querySelectorAll('a');[-27,659,047] document.getElementsByName('name'); [-----79,022] document.querySelectorAll('[name=name]');[-22,972,151] document.getElementsByClassName('classname'); [-----67,003] document.querySelectorAll('[class = classname]');

點評:?
getElementBy
系列的執行速度基本都是querySelectorAll的100+倍


  • 瀏覽器2: Firefox 31.0 32-bit
[226,165,531] document.getElementsByTagName('a'); [----144,576] document.querySelectorAll('a');[-10,197,651] document.getElementsByName('name'); [----119,340] document.querySelectorAll('[name=name]');[227,034,307] document.getElementsByClassName('classname'); [----104,720] document.querySelectorAll('[class = classname]');

點評:?
Firefox上getElementsByTagNamegetElementsByClassName比Chrome快了10倍,而其余四個則相差無幾,有高人能解析下原因么?


  • 瀏覽器3: IE 11.0.9600
[--1,797,107] document.getElementsByTagName('a'); [-----59,829] document.querySelectorAll('a');[--1,344,551] document.getElementsByName('name'); [-----13,706] document.querySelectorAll('[name=name]');[--1,710,804] document.getElementsByClassName('classname'); [------8,938] document.querySelectorAll('[class = classname]');

點評:?
IE比FF和Chrome慢的太多了。不過沒關系:速度不夠,情懷來湊嘛。

主要是選擇器的區別和是否實時的區別。

1.選擇器

  • querySelector**

querySelector和querySelectorAll 是HTML5新引入的功能類似jQuery的選擇器。前者返回按文檔順序返回指定元素節點的子樹中匹配選擇器的第一個元素,沒有則返回null。后者返回按文檔順序返回指定元素節點的子樹中匹配選擇器的元素集合,如果沒有匹配返回空集合。以querySelectorAll為例說明。
querySelectorAll('selectors'),其中的selectors可以包含多個CSS選擇器,可以是類選擇器,也可以是ID選擇器,也可以是Tag類型選擇器,當然也可以是它們的混合。

elements = document.querySelectorAll('div.foo');//返回所有帶foo類樣式的div
  • getElementsBy***

getElementsBy***只能根據特定選擇器尋找。getElementById(id)選擇器內容是id名,返回擁有第一個這個id的對象引用。比如有一個
<div id="no1"><div>元素。可以用querySelector('#no1')或者getElementById('no1')獲取。getElementsByTagName的選擇器tagname,getElementsByName的選擇器是標簽的name屬性值,getElementsByClassName的選擇器是類名,都是直接寫名字,而不需要加#,.等標識符。

2.實時性
querySelector**返回的是非實時的。而getElementBy**返回的是實時的。
用以下的例子說明:

<div id="container"><div></div><div></div> </div> //首先選取頁面中id為container的元素 container=document.getElementById('#container'); console.log(container.childNodes.length)//結果為2 //然后通過代碼為其添加一個子元素 container.appendChild(document.createElement('div')); //這個元素不但添加到頁面了,這里的變量container也自動更新了 console.log(container.childNodes.length)//結果為3

發現getElementBy的結果返回的實時的結果,而如果用querySelector,結果還是原來的結構返回結果。

轉載于:https://www.cnblogs.com/shuman/p/3972910.html

總結

以上是生活随笔為你收集整理的[label][转载][JavaSript]querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。