首頁 > web前端 > js教程 > 原生強大的DOM選擇器querySelector詳細介紹(程式碼附上)

原生強大的DOM選擇器querySelector詳細介紹(程式碼附上)

亚连
發布: 2018-05-19 13:52:10
原創
1926 人瀏覽過

這篇文章主要介紹了原生的強大DOM選擇器querySelector一些相關知識,需要的朋友可以參考下

在傳統的JavaScript 開發中,查找DOM 往往是開發人員遇到的第一個頭痛的問題,原生的JavaScript 所提供的DOM 選擇方法並不多,僅限於透過tag, name, id 等方式來查找,這顯然是遠遠不夠的,如果想要進行更為精確的選擇不得不要使用看起來非常繁瑣的正規表示式,或使用某個函式庫。事實上,現在所有的瀏覽器廠商都提供了querySelector 和querySelectorAll 這兩個方法的支持,甚至就連微軟也派出了IE 8 作為支持這一特性的代表,querySelector 和querySelectorAll 作為查找DOM 的又一途徑,極大地方便了開發者,使用它們,你可以像使用CSS 選擇器一樣快速地查找到你需要的節點。

querySelector 和 querySelectorAll 的使用非常的簡單,就像標題說到的一樣,它和 CSS 的寫法完全一樣,對於前端開發人員來說,這是難度幾乎為零的一次學習。假如我們有一個id 為test 的p,為了得到到這個元素,你也許會像下面這樣:

document.getElementById("test");
#現在我們來試試使用新方法來取得這個p:

document.querySelector("#test");
document.querySelectorAll("#test")[0];
登入後複製

下面是個小示範:

我是id 為test 的p

感覺差別不大是吧,但如果是稍微複雜點的情況,原始的方法將變得非常麻煩,這時候querySelector 和querySelectorAll 的優勢就發揮出來了。例如接下來這個例子,我們將在document 中選取class 為test 的p 的子元素p 的第一個子元素,當然這很拗口,但是用本文的新方法來選擇這個元素,比用言語來描述它還要簡單。

document.querySelector("p.test>p:first-child");
document.querySelectorAll("p.test>p:first-child")[0];
登入後複製

下面是個小演示:

我是層裡的p 標籤

現在應該對於querySelector、querySelectorAll 方法中的參數已經非常明白了,是的,它接收的參數和CSS 選擇器完全一致。 querySelector 和 querySelectorAll 的差別在於 querySelector 用來取得一個元素,而querySelectorAll 可以取得多個元素。 querySelector 將傳回符合的第一個元素,如果沒有符合的元素則傳回 Null。 querySelectorAll 傳回包含符合的元素的數組,如果沒有符合的元素則傳回的陣列為空。在本文最後一個範例中,我們使用 querySelectorAll 為所有 class 為 emphasis 的元素加粗顯示。

var emphasisText = document.querySelectorAll(".emphasis");
for( var i = 0 , j = emphasisText.length ; i < j ; i++ ){
  emphasisText[i].style.fontWeight = "bold";
}
登入後複製

這是原生方法,比起jquery速度快,缺點是IE6、7不支援。

W3C的規範與庫中的實作

querySelector:return the first matching Element node within the node's subtrees. If there is no such node, the method must return null .(傳回指定元素節點的子樹中匹配selector的集合中的第一個,如果沒有匹配,返回null)

querySelectorAll:return a NodeList containing all of the matching Element nodes within the node's subtrees, in document order. If there are no such nodes, the method must return an empty NodeList. (返回指定元素節點的子樹中匹配selector的節點集合,採用的是深度優先預查找;如果沒有匹配的,這個方法返回空集合)

這在BaseElement 為document的時候,沒有什麼問題,各瀏覽器的實作基本上一致;但是,當BaseElement 為一個普通的dom Node的時候(支援這兩個方法的dom Node ),瀏覽器的實作就有點奇怪了,舉個例子:

<p class= "test"  id= "testId" > 
   <p><span>Test</span></p> 
</p> 
<script type= "text/javascript" >   
   var  testElement= document.getElementById( &#39;testId&#39; ); 
   var  element = testElement.querySelector( &#39;.test span&#39; ); 
   var  elementList = document.querySelectorAll( &#39;.test span&#39; ); 
   console.log(element); // <span>Test</span>
   console.log(elementList); // 1  
</script>
登入後複製

按照W3C的來理解,這個例子應該回傳:element:null;elementList:[];因為作為baseElement的testElement裡面根本沒有符合selectors的匹配子節點;但瀏覽器卻好像無視了baseElement,只在乎selectors,也就是說此時baseElement近乎document;這和我們的預期結果不合,也許隨著瀏覽器的不斷升級,這個問題會得到統一口徑!

人的智慧總是無窮的,Andrew Dupont發明了一種方法暫時修正了這個怪問題,就是在selectors前面指定baseElement的id,限制匹配的範圍;這個方法被廣泛的應用在各大流行框架中;

Jquery的實作:

var  oldContext = context,
old = context.getAttribute( "id"  ),
nid = old || id,
登入後複製
try  {
	if  ( !relativeHierarchySelector || hasParent ) {
   	return  makeArray( context.querySelectorAll( "[id=&#39;"  + nid + "&#39;] "  + query ), extra );
 	}  
} 
catch (pseudoError) {} 
finally {
	if  ( !old ) {
	 	oldContext.removeAttribute( "id"  );
	}
}
登入後複製

先不看這點程式碼中其他的地方,只看他如何實作這個方法的;這點程式碼是JQuery1.6的片段;當baseElement沒有ID的時候,給他設定一個id = "__sizzle__”,然後再使用的時候加在selectors的前面,做到範圍限制;context.querySelectorAll( "[id='" nid "'] " query ;最後,因為這個ID本身不是baseElement應該有的,所以,還要移除:oldContext.removeAttribute( "id" ); ,Mootools的實作:

var  currentId = _context.getAttribute( &#39;id&#39; ), slickid = &#39;slickid__&#39; ;
_context.setAttribute( &#39;id&#39; , slickid);
_expression = &#39;#&#39;  + slickid + &#39; &#39;  + _expression;
context = _context.parentNode;
登入後複製

Mootools和Jquery类似:只不过slickid = 'slickid__';其实意义是一样的;方法兼容性:FF3.5+/IE8+/Chrome 1+/opera 10+/Safari 3.2+;IE 8 :不支持baseElement为object;

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Node.Js实现端口重用步骤详解

js继承中的方法重写重点讲解

js方法的重写和重载的技巧详解

以上是原生強大的DOM選擇器querySelector詳細介紹(程式碼附上)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板