querySelector 和 querySelectorAll 在傳統的 JavaScript 開發中,查找 DOM 往往是開發人員遇到的第一個頭疼的問題,原生的 JavaScript 所提供的 DOM 選擇方法並不多,僅僅局限於通過 tag, name, id 等方式來查找,這顯然是遠遠不夠的, ...
querySelector 和 querySelectorAll
在傳統的 JavaScript 開發中,查找 DOM 往往是開發人員遇到的第一個頭疼的問題,原生的 JavaScript 所提供的 DOM 選擇方法並不多,僅僅局限於通過 tag, name, id 等方式來查找,這顯然是遠遠不夠的,如果想要進行更為精確的選擇不得不使用看起來非常繁瑣的正則表達式,或者使用某個庫。事實上,現在所有的瀏覽器廠商都提供了 querySelector
和 querySelectorAll
這兩個方法的支持,甚至就連微軟也派出了 IE 8 作為支持這一特性的代表,querySelector 和 querySelectorAll 作為查找 DOM 的又一途徑,極大地方便了開發者,使用它們,你可以像使用 CSS 選擇器一樣快速地查找到你需要的節點。
querySelector
querySelector 和 querySelectorAll 的使用非常的簡單,就像標題說到的一樣,它和 CSS 的寫法完全一樣,對於前端開發人員來說,這是難度幾乎為零的一次學習。假如我們有一個 id 為 test 的 DIV,為了獲取到這個元素,你也許會像下麵這樣:
document.getElementById("test");
現在我們來試試使用新方法來獲取這個 DIV:
document.querySelector("#test");
document.querySelectorAll("#test")[0];
獲取文檔中 class=”example” 的第一個 <p>
元素:
document.querySelector("p.example");
獲取文檔中有 “target” 屬性的第一個 <a>
元素:
document.querySelector("a[target]");
假定你選擇了兩個選擇器: <h2>
和 <h3>
元素。 以下代碼將為文檔的第一個 <h2>
元素添加背景顏色:
<h2>A h2 element</h2> <h3>A h3 element</h3> document.querySelector("h2, h3").style.backgroundColor = "red";//返回h2或者h3的首個元素
但是,如果文檔中 <h3>
元素位於 <h2>
元素之前,<h3>
元素將會被設置指定的背景顏色。
<h3>A h3 element</h3> <h2>A h2 element</h2> document.querySelector("h2, h3").style.backgroundColor = "red";
使用這兩個方法無法查找帶偽類狀態的元素,比如querySelector(':hover')
不會得到預期結果。
querySelectorAll
該方法返回所有滿足條件的元素,結果是個nodeList集合。查找規則與前面所述一樣。
elements = document.querySelectorAll('div.foo');//返回所有帶foo類樣式的div
但需要註意的是返回的nodeList集合中的元素是非實時(no-live)的,想要區別什麼是實時非實時的返回結果,請看下例:
<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
通過上面的例子就很好地理解了什麼是會實時更新的元素。document.getElementById
返回的便是實時結果,上面對其添加一個子元素後,再次獲取所有子元素個數,已經由原來的2個更新為3個(這裡不考慮有些瀏覽器比如Chrome會把空白也解析為一個子節點)。
感覺區別不大是吧,但如果是稍微複雜點的情況,原始的方法將變得非常麻煩,這時候 querySelector 和 querySelectorAll 的優勢就發揮出來了。比如接下來這個例子,我們將在 document 中選取 class 為 test 的 div 的子元素 p 的第一個子元素,當然這很拗口,但是用本文的新方法來選擇這個元素,比用言語來描述它還要簡單。
document.querySelector("div.test>p:first-child"); document.querySelectorAll("div.test>p:first-child")[0];
我們使用 querySelectorAll 給所有 class 為 emphasis 的元素加粗顯示。
var emphasisText = document.querySelectorAll(".emphasis"); for( var i = 0 , j = emphasisText.length ; i < j ; i++ ){ emphasisText[i].style.fontWeight = "bold"; }
這是原生方法,比起jquery速度快
關於轉義
我們知道反斜杠是用來轉義用的,比如在字元串里我們想表示空字元就使用'\b'
,換行'\n'
。同樣,在提供給querySelector和querySelectorAll的參數也支持轉義,瞭解這點非常重要。
先看個例子,比如我們有個div它的樣式類為'foo:bar'
,當然我知道你一般不會這樣寫。當我們需要選擇它的時候,就需要將其中的冒號進行轉義,否則拋錯。
<div class="foo:bar"></div>
瀏覽器報怨表示不是一個合法的選擇語句。
同時,有趣的事情來了,或許你以為將冒號直接轉義就解決問題了。
同樣,也表示非法。原因就在於反斜杠在字元串中本身就表示轉義的意思,它於冒號結合轉不出東西來,於是拋錯。
所以正確的做法是將反斜杠轉義後'.foo\:bar'
再傳遞給querySelector,後者在接收到'.foo\:bar'
這個參數後,字元串將兩個反斜杠轉義成一個,然後querySelector前面得到的一個反斜杠與冒號結合進行轉義得到正確結果。
也就是說經歷兩次轉義,一次是字元串當中,一次是querySelector解析參數時。
理解這點後,可以來看一個更有趣的例子了。比如我們要選擇類名裡面含反斜杠的元素。是的,我們需要一共使用四個反斜杠!才能正常工作。
<div class="foo\bar"></div>