0

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

patad
  • 9,364
  • 11
  • 38
  • 44
  • what im trying to do is: if(wrap.getElementsByClassName('ar').length){ do.. } it works fine if FF but not in ie since it doesnt support getElementsByClassName – patad Jan 15 '10 at 21:25
  • 1
    the "ar a = new Array();" line... shouldn't it be "var a = new Array();" or better yet, "var a = [];" – scunliffe Jan 15 '10 at 21:26
  • oh, 'ar' sliped in i thought new Array was better than just [] anyway, ive tried both, make no difference =/ – patad Jan 15 '10 at 21:31

4 Answers4

5
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
  • 1,359
  • 3
  • 15
  • 37
  • 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 Jan 15 '10 at 21:40
  • You beat me by 5 minutes, though! – bobince Jan 15 '10 at 21:42
  • 1
    aren't you a nice guy ;-) gave it to bobince, thumbed you up though thanks alot! – patad Jan 15 '10 at 21:43
  • Knowledge beats speed in my world. Especially if the time difference is as low as 5 minutes. ;) – BYK Jan 15 '10 at 21:44
3

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.

Community
  • 1
  • 1
bobince
  • 528,062
  • 107
  • 651
  • 834
  • Good point about various characters. =) – BYK Jan 15 '10 at 21:35
  • 1
    ur totally right, good point! i will not use this again then but atm i KNOW for sure that classname will be "special" and nothing else, so I guess it work in this particular case – patad Jan 15 '10 at 21:40
1

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
  • 56,361
  • 10
  • 99
  • 123
  • ...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 Jan 15 '10 at 21:30
  • when I debugg and use \\b + classname \\b, I get: re = /\bspecial\b/ – patad Jan 15 '10 at 21:33
0

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;
}
Joshua Shannon
  • 2,723
  • 17
  • 11