Home >Web Front-end >JS Tutorial >Let's talk about the difference and connection between querySelector and querySelectorAll_javascript skills

Let's talk about the difference and connection between querySelector and querySelectorAll_javascript skills

WBOY
WBOYOriginal
2016-05-16 17:54:051012browse

Let's first talk about what these two methods should return according to W3C specifications:
querySelector:

return the first matching Element node within the node's subtrees. If there is no such node, the method must return null. (Returns the first in the set that matches the selector in the subtree of the specified element node. If there is no match, returns 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 matching selector in the subtree of the specified element node. The node set uses depth-first pre-search; if there is no match, this method returns an empty set)

Usage:

Copy code The code is as follows:

var element = baseElement.querySelector(selectors);
var elementList = baseElement.querySelectorAll(selectors);

There is no problem when BaseElement is a document, and the implementation of each browser is basically the same; however, when BaseElement is an ordinary dom Node (dom Node that supports these two methods), The browser implementation is a bit strange, for example:
Copy code The code is as follows:


Test



< script type="text/javascript">
var testElement= document.getElementById('testId');
var element = testElement.querySelector('.test span');
var elementList = document. querySelectorAll('.test span');
console.log(element); // Test
console.log(elementList); // 1

According to the W3C understanding, this example should return: element: null; elementList: []; because there is no matching child node that matches selectors in testElement as baseElement; but the browser seems to Ignore baseElement and only care about selectors, which means baseElement is almost document at this time; this is inconsistent with our expected results. Maybe as browsers continue to upgrade, this issue will be unified!
Human wisdom is always infinite. Andrew Dupont invented a method to temporarily correct this strange problem, which is to specify the id of baseElement in front of selectors to limit the matching range; this method is widely used in major popular frameworks in;
Jquery implementation:
Copy code The code is as follows:

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" );}
}

Don’t look at other places in this code, just look at how it implements this method; this code is JQuery1.6 Fragment; when baseElement has no ID, set an id = "__sizzle__" for it, and then add it in front of selectors when using it to limit the range; context.querySelectorAll( "[id='" nid "'] " query ; Finally, because this ID itself is not what baseElement should have, it needs to be removed: oldContext.removeAttribute( "id" );
, Mootools implementation:
Copy code The code is as follows:

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__'; In fact, the meaning is the same;

Method compatibility: FF3.5 /IE8 /Chrome 1 /opera 10 /Safari 3.2;

IE 8: baseElement is not supported as object;

Thank you very much for Daniel JK’s reply and provided another method.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn