JS中 querySelector 與 getElementById 方法區別
1. 概述
在看代碼的時候發現基本上都是用 querySelector()
和 querySelectorAll()
來獲取元素,疑惑為什麼不用 getElementById()
。
可能因為自己沒用過那兩個,所以並不清楚原因所在。
1.1 querySelector() 和 querySelectorAll() 的用法
querySelector() 方法
定義:querySelector()
方法返回文檔中匹配指定 CSS 選擇器的一個元素;
註意:uerySelector()
方法僅返回匹配指定選擇器的第一個元素。如果你需要返回所有的元素,請用 querySelectorAll() 方法替代;
語法:document.querySelector(CSS selectors);
參數值:String 必須。指定一個或多個匹配元素的 CSS 選擇器。使用它們的 id, 類, 類型, 屬性, 屬性值等來選取元素。
對於多個選擇器,使用逗號隔開,返回一個匹配的元素。
返回值: 匹配指定 CSS 選擇器的第一個元素。 如果沒有找到,返回 null。如果指定瞭非法選擇器則 拋出 SYNTAX_ERR 異常。
querySelectorAll() 方法
定義: querySelectorAll()
方法返回文檔中匹配指定 CSS 選擇器的所有元素,返回 NodeList 對象;
NodeList 對象表示節點的集合。可以通過索引訪問,索引值從 0 開始;
提示: 可使用 NodeList 對象的 length 屬性來獲取匹配選擇器的元素屬性,然後遍歷所有元素,從而獲取想要的信息;
語法: elementList = document.querySelectorAll(selectors);
elementList
是一個靜態的 NodeList
類型的對象;
selectors
是一個由逗號連接的包含一個或多個 CSS
選擇器的字符串;
參數值: String
必須。指定一個或多個匹配 CSS 選擇器的元素。可以通過 id
, class
, 類型, 屬性, 屬性值等作為選擇器來獲取元素。
多個選擇器使用逗號(,)分隔。
返回值:
一個 NodeList
對象,表示文檔中匹配指定 CSS 選擇器的所有元素。
NodeList
是一個靜態的 NodeList
類型的對象。如果指定的選擇器不合法,則拋出一個 SYNTAX_ERR
異常。
1.2 getElement(s)Byxxxx 的用法
getElementById() 方法
定義: getElementById()
方法可返回對擁有指定 ID 的第一個對象的引用。
如果沒有指定 ID 的元素返回 null
;
如果存在多個指定 ID 的元素則返回第一個;
如果需要查找到那些沒有 ID 的元素,你可以考慮通過CSS選擇器使用 querySelector();
語法: document.getElementById(elementID);
參數值: String
必須。元素ID屬性值。
返回值: 元素對象 指定ID的元素
getElementsByTagName() 方法
定義: getElementsByTagName()
方法可返回帶有指定標簽名的對象的集合;
提示: 參數值 “*” 返回文檔的所有元素;
語法: document.getElementsByTagName(tagname)
參數: String
必須 要獲取元素的標簽名;
返回值: NodeList
對象 指定標簽名的元素集合
getElementsByClassName() 方法
定義: getElementsByClassName()
方法返回文檔中所有指定類名的元素集合,作為 NodeList
對象。
NodeList
對象代表一個有順序的節點列表。NodeList
對象 可通過節點列表中的節點索引號來訪問表中的節點(索引號由0開始)。
提示: 可使用 NodeList 對象的 length 屬性來確定指定類名的元素個數,並循環各個元素來獲取需要的那個元素。
語法: document.getElementsByClassName(classname)
參數: String 必須 需要獲取的元素類名。 多個類名使用空格分隔,如 “test demo
“;
返回值: NodeList 對象,表示指定類名的元素集合。元素在集合中的順序以其在代碼中的出現次序排序。
2. 區別
2.1 getElement(s)Byxxxx 獲取的是動態集合,querySelector 獲取的是靜態集合
動態就是選出的元素會隨文檔改變,靜態的不會 取出來之後就和文檔的改變無關瞭。
示例1:
<body> <ul id="box"> <li class="a">測試1</li> <li class="a">測試2</li> <li class="a">測試3</li> </ul> </body> <script type="text/javascript"> //獲取到ul,為瞭之後動態的添加li var ul = document.getElementById('box'); //獲取到現有ul裡面的li var list = ul.getElementsByTagName('li'); for(var i =0; i < list.length; i++){ ul.appendChild(document.createElement('li')); //動態追加li } </script>
上述代碼會陷入死循環,i < list.length 這個循環條件。
因為在第一次獲取到裡面的 3 個 li 後,每當往 ul 裡添加瞭新元素後,list便會更新其值,重新獲取ul裡的所有li。
也就是 getElement(s)Byxxxx
獲取的是動態集合,它總會隨著 dom
結構的變化而變化。
也就是每一次調用 list 都會重新對文檔進行查詢,導致無限循環的問題。
示例1 修改:
將 for 循環條件修改為 i < 4,結果 在 ul 裡新添加瞭4個元素,所有現在插入的 li 標簽數量是7。
<body> <ul id="box"> <li class="a">測試1</li> <li class="a">測試2</li> <li class="a">測試3</li> </ul> </body> <script type="text/javascript"> var ul = document.getElementById('box'); var list = ul.getElementsByTagName('li'); for(var i = 0; i < 4; i++){ ul.appendChild(document.createElement('li')); } console.log('list.length:',list.length); </script>
JavaScript
中 querySelector
與 getElementById
方法的區別_javascript
示例2:
下述代碼靜態集合體現在 .querySelectorAll(‘li')
獲取到 ul 裡所有 li 後,不管後續再動態添加瞭多少 li,都是不會對其參數影響。
<body> <ul id="box"> <li class="a">測試1</li> <li class="a">測試2</li> <li class="a">測試3</li> </ul> </body> <script type="text/javascript"> var ul = document.querySelector('ul'); var list = ul.querySelectorAll('li'); for(var i = 0; i < list.length; i++){ ul.appendChild(document.createElement('li')); } console.log('list.length:',list.length); //輸出的結果仍然是 3,不是此時 li 的數量 6 </script>
JavaScript
中 querySelector
與 getElementById
方法的區別_javascript_02
為什麼要這樣設計呢?
在 W3C 規范中對 querySelectorAll 方法有明確規定:
The NodeList object returned by the querySelectorAll() method must be static ([DOM], section 8).
我們再看看在 Chrome 上面是個什麼樣的情況:
document.querySelectorAll('a').toString(); // return "[object NodeList]" document.getElementsByTagName('a').toString(); // return "[object HTMLCollection]"
HTMLCollection 在 W3C 的定義如下:
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
規范。
這樣說有點難理解,看看下面的例子會比較好理解:
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 對象 。
2.2 接收的參數不同
querySelectorAll
方法接收的參數是一個 CSS 選擇符;
getElementsBy
系列接收的參數隻能是單一的 className
、tagName
和 name
;
var c1 = document.querySelectorAll('.b1 .c'); var c2 = document.getElementsByClassName('c'); var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');
註意:querySelectorAll
所接收的參數是必須嚴格符合 CSS 選擇符規范的
下面這種寫法,將會拋出異常(CSS 選擇器中的元素名,類和 ID 均不能以數字為開頭)。
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);
2.3 瀏覽器兼容不同
querySelectorAll 已被 IE 8+、FF 3.5+、Safari 3.1+、Chrome 和 Opera 10+ 支持 ;
getElementsBy 系列,以最遲添加規范中的 getElementsByClassName 為例,IE 9+、FF 3 +、Safari 3.1+、Chrome 和 Opera 9+ 都已經支持;
到此這篇關於JavaScript中 querySelector 與 getElementById 方法區別的文章就介紹到這瞭,更多相關JavaScript中 querySelector 與 getElementById 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Manipulation-TypeScript DOM操作示例解析
- javascript的基礎交互詳解
- Javascript DOM的簡介,節點和獲取元素詳解
- JavaScript文檔對象模型DOM
- JavaScript Dom對象的操作