954,600 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Can't set event listeners to multiple elements of same class

Hi. I'm trying to add event listeners to multiple elements of the same class. The DOM is something like this:

<body>
....
.......
..........
       <ul class="x">
             <li class="a">
                 ....
                 ...
                 <span class="someclass">
                      [
                      <a href="http://someurl/x1>link text</a>
                      ]
                 </span>
                 </li>
             <li class="b>
                 ....
                 .....
                 <span class="someclass>
                    [
                      <a href="http://someurl/x1>link text</a>
                    ]
                  </span>
               </li>  
       <ul class="y">
               <li class="a">
                  ....
                  ...
                 <span class="someclass">
                      [
                      <a href="http://someurl/x1>link text</a>
                      ]
                    .... 
      <ul class="z">
               <li class="a">
                  ....
                  ...
                 <span class="someclass">
                      [
                      <a href="http://someurl/x1>link text</a>
                      ]
                  ....


I want to attach an event listener to each of the element inside elements of class "someclass".

Here's what I did

for(var i in document.getElementsByClassName('someclass'))
{
document.getElementsByClassName('someclass')[i].childNodes[1].addEventListener('click', function(){return alert("link clicked");},false);
}


When I run this (in Firebug) I get this error:TypeError: document.getElementsByClassName('someclass')[i].childNodes is undefined

Even though document.getElementsByClassName('someclass')[S].hasChildNodes(); evaluates to true. (S is any integer literal: 0,1,2...upto to the length of the array-1)>>>document.getElementsByClassName('someclass')[2].hasChildNodes();

>>>true
Not sure what I'm doing wrong; are there any alternate ways to do this? Thanks.

zvn
Newbie Poster
3 posts since Dec 2009
Reputation Points: 10
Solved Threads: 1
 

I think the for (var i in ...) is the problem. My guess is i is not an integer, but an object (element).

I think you should store the document.getElementsByClassName('someclass') in an array and loop through it using for (i=0; i

pritaeas
Posting Expert
Moderator
5,484 posts since Jul 2006
Reputation Points: 653
Solved Threads: 875
 

ZVN,

As Pritaes said plus ......

Unfortunately, .getElementsByClassName is far from safe. Too many browsers don't support it. So you have to be a bit old fashioned and do it longhand with .getElementsByTagName then test for .className in the loop.

Try this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Airshow :: Untitled</title>
<style type="text/css">
{}
</style>

<script>
onload = function(){
	var elArray = document.getElementsByTagName('span');
	for(var i=0; i<elArray.length; i++){
		if(elArray[i].className !== 'someclass') continue;
		var elArray2 = elArray[i].getElementsByTagName('a');
		for(var j=0; j<elArray2.length; j++){
			elArray2[j].onclick = function(){
				return alert(this.innerHTML + ' : ' + this.href);
				return false;
			};
		}
	}
}
</script>
</head>

<body>

<ul class="x">
<li class="a"><span class="someclass"><a href="http://someurl/x1/A">link text 1</a></span></li>
<li class="b"><span class="someclass"><a href="http://someurl/x1/B">link text 2</a></span></li>
</ul>

<ul class="y">
<li class="a"><span class="someclass"><a href="http://someurl/x1/C">link text 3</a></span>
</ul>

<ul class="z">
<li class="a"><span class="someclass"><a href="http://someurl/x1/D">link text 4</a></span>
</ul>

</body>
</html>

As you see, I have used !Doctype XHTML but I think it should work for XML too.Airshow

Airshow
WiFi Lounge Lizard
Moderator
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
 

Thanks for the example Airshow. Just one more reason to use jQuery for me ;)

pritaeas
Posting Expert
Moderator
5,484 posts since Jul 2006
Reputation Points: 653
Solved Threads: 875
 

jQuery, Prototype etc. are good but tricky. I encourage novices to learn JS basics before trying to use these libs. People can't run before they can walk.

My rules (only occasionally broken) : if it's a jQuery (etc.) question then it gets a jQuery answer; otherwise basic JS. I might steer someone in the direction of jQuery if I think the problem is large enough to warrant the overhead and the poster appears advanced enough to cope with it.

Airshow

Airshow
WiFi Lounge Lizard
Moderator
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
 

Thank you Airshow, pritaeas for the help!:) My script is now working as expected. (..and I'll definitely start reading a book on jQuery/YUI once I'm confident enough with the basic concepts of Javascript).

--

zvn
Newbie Poster
3 posts since Dec 2009
Reputation Points: 10
Solved Threads: 1
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: