-
-
Save jed/991057 to your computer and use it in GitHub Desktop.
// inspired by @techpriester: https://gist.github.com/988627 | |
function( | |
a, // take a simple selector like "name", "#name", or ".name", and | |
b // an optional context, and | |
){ | |
a = a.match(/^(\W)?(.*)/); // split the selector into name and symbol. | |
return( // return an element or list, from within the scope of | |
b // the passed context | |
|| document // or document, | |
)[ | |
"getElement" + ( // obtained by the appropriate method calculated by | |
a[1] | |
? a[1] == "#" | |
? "ById" // the node by ID, | |
: "sByClassName" // the nodes by class name, or | |
: "sByTagName" // the nodes by tag name, | |
) | |
]( | |
a[2] // called with the name. | |
) | |
} |
function(a,b){a=a.match(/^(\W)?(.*)/);return(b||document)["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2])} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Jed Schmidt <http://jed.is> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "cssSelect", | |
"description": "select DOM elements by ID, tag name, or class name", | |
"keywords": [ | |
"dom", | |
"css", | |
"id", | |
"class", | |
"tag" | |
] | |
} |
@atk yep that getElementsByClassName just bit me while working on a Windows Gadget. I'm going to put a check around my copy, make it return null or something. Crazy thing is, I was selecting by id "#", so how did it end up with that by class name function anyways. Hmm...
I ran a few tests. Turns out the logic to decide which getElement(s)By method to use, wrongly drops to "sByClassName" for # selector.
If we isolated the logic into a function called "m". Then the function would return:
m('#foo')
getElementsByClassName
m('.foo')
getElementsByClassName
m('foo')
getElementsByTagName
It works well for class and tag selectors but erroneously returns the class-getter for an id selector.
My proposed fix just adds an explicit check for the class selector:
"getElement" + ( // obtained by the appropriate method calculated by
a[1] == "#"
? "ById" // the node by ID,
: a[1] == '.'
? "sByClassName" // the nodes by class name, or
: "sByTagName" // the nodes by tag name
)
Isolating this into a method, "m", and testing it yields the following results:
m('#foo')
getElementById
m('.foo')
getElementsByClassName
m('foo')
getElementsByTagName
Tests/specs around this snippet would have easily caught this. Let's add them.
I hope you merge this fix in. And thanks for the share @jed, this is a sweet little helper!
For anyone who really wants/needs the "getElementsByClassName" support in IE7 or below (really? why!?! Oh you are working on a Windows Gadget you say, ok then... but the blood of innocent web standards is on your head) check out http://ejohn.org/blog/getelementsbyclassname-speed-comparison/
thanks @rudylattae. looks like some removed parens around (b=a[1])
caused a bad order of operations. it's fixed, so thanks for pointing this out!
Awesome, the fix works brilliantly!
I would advice you about that IE<9 doesn't support getElementsByClassName
(source: caniuse.com) contrary to rudylattae comment.
You can save another byte by removing ^
. Due to how the regular expressions is executed this does not make a difference in your case. And by the way, I tried to create getElementsByClassName
in 140 bytes, which is missing in Internet Explorer <9.0, but currently it still is 162 bytes.
Another btw.: why use
match
whenexec
will do the same? How does the saying go: a byte saved...Other than that: older IEs don't support .getElementsByClassName. That's gonna be one for the wishlist, ain't it?