views:

117

answers:

4

I am trying to get some elems with the classname "special". I found the following script online, but it only returns an empty array.

Does anyone see what's wrong?

getElementsByClassName = function (node, classname){
 var a = [],
    re = new RegExp('\b' + classname + '\b'),
    els = node.getElementsByTagName("*"),
    l = els.length,
    i;

 for (i = 0; i < l; i += 1) {
  if (re.test(els[i].className)) {
      a.push(els[i]);
  }
 }
 console.log(a)
 return a;
}

var wrap = document.getElementById('wrap');
getElementsByClassName(wrap, 'special')

wrap contains 22 children, the last one is <p class="special">Lorem</p>, and in firebug I get all the way down to finding the node with the classname, but then it jumps the a.push. Im lost!

edit: okay so it does work now, it would still be interesting though to know why console.log(a) return an empty array

+1  A: 

Maybe I'm mistaken, but I don't think that re.test(els[i].className) is going include the \b word boundaries, so the regex fails.

That is to say that you're just passing "special" without any space or quotes or other boundary characters around it.

Jay
...so try it without the \b at all ... Oh, or maybe actually you need '\\b' + classname + '\\b'. Now I'm just shooting in the dark at this.
Jay
when I debugg and use \\b + classname \\b, I get:re = /\bspecial\b/
meow
+5  A: 
re = new RegExp('\b' + classname + '\b')

Should be

re = new RegExp('\\b' + classname + '\\b')

Also you should use "var " in the beginning of the variable declerations.

BYK
right now I feel like a dickheadthat actually did work THIS time but not the first time hmmmI think perhaps I got a bit confused when I saw re = /\bspecial\b/ when debuggingwell thanks alot for that!
meow
Don't feel bad, it is a normal mistake =) Also you should check out the points bobince mentioned in his/her answer. Actually you can make that one the "accepted answer" since it has much more information than mine =)
BYK
You beat me by 5 minutes, though!
bobince
aren't you a nice guy ;-)gave it to bobince, thumbed you up thoughthanks alot!
meow
arrrh now I can't decide :-S
meow
Knowledge beats speed in my world. Especially if the time difference is as low as 5 minutes. ;)
BYK
+2  A: 

re = new RegExp('\b' + classname + '\b'),

\b in a string literal is a backspace character. They meant:

var re= new RegExp('\\b' + classname + '\\b');

However this is still wrong, because:

  1. it won't work for any classnames that contain non-ASCII or non-alphanumeric characters, as that would put the word boundaries in the wrong place;

  2. classnames may contain characters that have special meaning in regex, such as .; these would need to be escaped.

You can find an alternative implementation that should match the standard document.getElementsByClassName interface better in this question.

bobince
Good point about various characters. =)
BYK
ur totally right, good point!i will not use this again thenbut atm i KNOW for sure that classname will be "special" and nothing else, so I guess it work in this particular case
meow
A: 

I think what you'll need to do is something like:

els = document.all ? node.all : node.getElementsByTagName("*")

I forget which versions of IE don't like node.getElementsByTagName('*'), but I know for sure it will fail in some versions. It will literally look for nodes with tagNames of asterisks!

The actual code I've used for this in the past looks like:

function getElementsByTagName(node, tag) {
    tag = tag || '*';
    var els = node.getElementsByTagName(tag);
    if( !els.length && (tag == '*' && node.all) ) els = node.all;
}
Josh
thanks for thatbut your looking for the tagname right, i was after the classname..
meow
The `getElementsByTagName("*")` bug was fixed in IE6.
bobince