1. 概述
在看代碼的時候發現基本上都是用 querySelector() 和 querySelectorAll() 來獲取元素,疑惑為什么不用 getElementById(),
可能因為自己沒用過那兩個,所以并不清楚原因所在,
1.1 querySelector() 和 querySelectorAll() 的用法
querySelector() 方法
定義: querySelector() 方法回傳檔案中匹配指定 CSS 選擇器的一個元素;
注意: querySelector() 方法僅回傳匹配指定選擇器的第一個元素,如果你需要回傳所有的元素,請用 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>

示例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>

為什么要這樣設計呢?
在 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+ 都已經支持;
2.4 querySelector 屬于 W3C 中的 Selectors API 規范 ,而 getElementsBy 系列屬于 W3C 的 DOM 規范
參考文章 (侵刪)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/335172.html
標籤:其他
上一篇:Java專案:前后端分離疫情防疫平臺設計和實作(java+springmvc+VUE+node.js+mybatis+mysql+springboot+redis+jsp)
