Selector.js
A small, fast, standard compilant, cross-browser implementation of an CSS3 Query Selector. Currently the Selector API (querySelectorAll) is only available in browsers based on WebKit (Safari and Chrome) and the soon to be released Firefox 3.1 and Internet Explorer 8. Similar selectors are also available in frameworks like base2, Dojo, Ext, jQuery, MooTools and Prototype. But, if you want to use query selection today without the bulky frameworks, our stand-alone selector is for you.
For fast queries, our implementation uses either DOM Level 3 XPath or pre-compiled JavaScript DOM traversal. The matched Element’s is always returned in a standard Array so iteration functions like forEach can be used (see Array.js). And to ease integration with other frameworks, the Selector class has hook functions to extend the result Element’s (patchElement) and Array (patchArray).
Selector.js supports all Simple selectors and Attribute selectors without namespace, all Combinators, Class selectors, ID selectors and all Pseudo-class selectors except the Dynamic pseudo-classes :hover and :visited, which isn’t possible with JavaScript/DOM. The other frameworks support a non-standard pseudo-selector :contains() and attribute compare operator !=, ours don’t.
Slickspeed benchmarks with comparison against other selector implementations, can be found here. Any call to the native querySelectorAll has been disabled. YUI selector is excluded, it’s one of the slower. NWMatcher and YASS are also excluded, without their result caching both are slow. Caching result is unrealible since DOMAttrModified events aren’t triggered when changing Element properties, it could also consume alot of memory. Some engines get a false speed boost by creating :nth- indices only once, ignoring that the node graph might change thus making any subsequent result incorrect. Most engines don’t support the -of-type pseudo selectors.
Intuitive usage, context node (document) optional:
// Normal constructor syntax:
new Selector('div > p').exec(document).forEach(function (e) {
e.style.color = 'red';
});
// Or, the shorthand syntax:
Selector('div > p', document).forEach(function (e) {
e.style.color = 'red';
});
Documentation
The generated online documentation can be found here.
To do
- Sort result elements in document order for group (comma) selectors. Currently working on a fast enough way to overcome WebKit’s lack of
compareDocumentPosition. - Use
RegExfor attribute comparison in Internet Explorer, it’s faster. - Improve the
:nth-indexing and lookup, maybe index elements when traversing. - Cache
:nth-indices for Internet Explorer too, and expire on DOM mutation. Currently in experimental stage (see source), needs further testing. For now, not possible. - Use native
querySelectorAllwhen available. Done, disabled in Slickspeed. - Internal benchmark of XPath and DOM traversal execution speeds, then choose the fastest at runtime. Tricky, since JavaScript limits timing to milliseconds. XPath no longer used.
- Compact the source, 11 K minified are a bit much. Might ditch the XPath part since it’s often slower. Done.
Changelog
- 2009-02-28 v0.6: Improved unique element (
:active,:focus,:rootand:target)selector speed by accessing them directly, avoiding traversal. Fixed bug when matching*elements with-of-typepseudo selectors. Better syntax error reporting. - 2009-02-11 v0.5: Improved
#id,:active,:focus,:rootand:targetspeed by exiting all ancestor selections when the match is found. - 2009-02-09 v0.4: Some speed improvements; Made
patchElementand optional function, only calling it when defined. Not usingsourceIndexas node hash. Direct insert into array instead of usingpush. - 2009-02-07 v0.3: Code cleanup and additional speed improvements. Not using
getElementByIdin Internet Explorer since it also matchesnameattribute. - 2009-02-01 v0.2: Rewrite, dropping XPath usage. Improved index caching. Compacted the source code further.
- 2009-01-20 v0.1: Initial public release.
Download
Minfied:Selector.js (7.7 K, ~3.2 K when gzipped)Source:Selector.js (15.3 K)- Modified Slickspeed test suite, no frameworks included: slickspeed.tar.gz (42 K)
License
GNU Lesser General Public License <http://www.gnu.org/licenses/lgpl-3.0.txt>
Author
Henrik Lindqvist <henrik.lindqvist@llamalab.com>
Comments
-
4. by brothercake on
-
3. by Stijn on
-
2. by Henrik Lindqvist on
-
1. by Diego Perini on