Introduction to the native powerful DOM selector querySelector, domqueryselector
In traditional JavaScript development, DOM searching is often the first headache for developers. There are not many DOM selection methods provided by native JavaScript, but only through tag, name, id, and other methods to search, which is obviously far from enough. If you want to make a more precise choice, you have to use a seemingly cumbersome regular expression, or use a library. In fact, all browser vendors now support the querySelector and querySelectorAll methods, and even Microsoft has sent IE 8 as a representative to support this feature, querySelector and querySelectorAll are another way to find the DOM, which greatly facilitates developers and allows you to quickly find the desired node like using the CSS selector.
The use of querySelector and querySelectorAll is very simple. Just like the title, it is exactly the same as CSS. for front-end developers, this is almost a learning difficulty. Assume that we have a DIV with id test. To obtain this element, you may look like the following:
Document. getElementById ("test ");
Now let's try a new method to get this DIV:
document.querySelector("#test");document.querySelectorAll("#test")[0];
Below is a small demonstration:
I am a div with id test.
The difference is not big, right? But if it is a little complicated, the original method will become very troublesome. At this time, the advantages of querySelector and querySelectorAll will be brought into play. For example, in the following example, We will select the first child element of the child element p of the div whose class is test in the document, however, using this new method to select this element is easier than describing it in words.
document.querySelector("div.test>p:first-child");document.querySelectorAll("div.test>p:first-child")[0];
Below is a small demonstration:
I am the p tag in the layer.
The parameters in querySelector and querySelectorAll methods are clearly understood. Yes, the parameters it receives are exactly the same as those in the CSS selector. The difference between querySelector and querySelectorAll is that querySelector is used to obtain an element, while querySelectorAll can obtain multiple elements. QuerySelector returns the first matched element. If no matched element exists, Null is returned. QuerySelectorAll returns an array containing matching elements. If no matching element exists, the returned array is null. In the last example of this article, we use querySelectorAll to show all elements whose classes are emphasis in bold.
var emphasisText = document.querySelectorAll(".emphasis");for( var i = 0 , j = emphasisText.length ; i < j ; i++ ){ emphasisText[i].style.fontWeight = "bold";}
This is a native method, which is faster than jquery. The disadvantage is that IE6 and 7 are not supported.
W3C specifications and library implementation
QuerySelector: return the first matching Element node within the node's subtrees. if there is no such node, the method must return null. (return the first child tree of the specified element node that matches the selector set. If no child tree matches the selector, return 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. (return the node set that matches the selector in the subtree of the specified element node, which adopts the depth-first pre-query. If no match exists, this method returns an empty set)
When BaseElement is document, there is no problem. The implementations of various browsers are basically the same. However, when BaseElement is a common dom Node (dom Node that supports these two methods), it is a bit strange to implement the browser. For example:
<div class= "test" id= "testId" > <p><span>Test</span></p> </div> <script type= "text/javascript" > var testElement= document.getElementById( 'testId' ); var element = testElement.querySelector( '.test span' ); var elementList = document.querySelectorAll( '.test span' ); console.log(element); // <span>Test</span> console.log(elementList); // 1 </script>
According to W3C's understanding, this example should return: element: null; elementList: []; because the testElement of the baseElement does not match the selectors matched subnode at all; however, the browser seems to ignore baseElement and only care about selectors. That is to say, baseElement is close to document at this time. This is not consistent with our expected results. Maybe, as the browser continues to upgrade, this problem will get a unified explanation!
The wisdom of people is always infinite. Andrew Dupont invented a method to temporarily correct this strange problem, that is, to specify the baseElement id before selectors and limit the matching range; this method is widely used in various popular frameworks;
Jquery implementation:
var oldContext = context,old = context.getAttribute( "id" ),nid = old || id,
try {if ( !relativeHierarchySelector || hasParent ) { return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); } } catch (pseudoError) {} finally {if ( !old ) { oldContext.removeAttribute( "id" );}}
Instead of looking at other aspects of the code, we only want to see how it implements this method. This code is a snippet of JQuery1.6. When baseElement does not have an ID, set an id = "_ sizzle _" for him, and add it to the front of selectors when it is used, so that the range is limited; context. querySelectorAll ("[id = '" + nid + "']" + query; finally, because the ID itself is not a baseElement, you also need to remove: oldContext. removeAttribute ("id");, implementation of Mootools:
var currentId = _context.getAttribute( 'id' ), slickid = 'slickid__' ;_context.setAttribute( 'id' , slickid);_expression = '#' + slickid + ' ' + _expression;context = _context.parentNode;
Mootools is similar to Jquery: Except slickid = 'slickid _ ', it actually has the same meaning. Method compatibility: FF3.5 +/IE8 +/Chrome 1 +/opera 10 +/Safari 3.2 +; IE 8: baseElement is not supported as an object;