Question

I would like to know how I can refer to a list item object if I had for example the following html list

<div id="subdiv_2">  
 <div id="subdiv_3">  
  <ul>  
   <li><a href="">Item1</a></li>  
   <li><a href="">Item2</a></li>  
   <li><a href="">Item3</a></li>    
  </ul>  
 </div>  
</div>  

How is it possible to register an onclick to the Item2 li without it having to have a unique elementId eg I can do so for subdiv_3 because it has a unique ID and isn't in the list by

document.getElementById('subdiv_3').addEventListener('click', function();, false);

My goal is ultimately to assign a function to each list object, for the number of list objects with unique parameters based upon the list object number eg:

for(i=0;i<list.length;i++){  
 "document.getElementById(list.item"+i+").addEventListener(\'click\',function("+i+");,false);";  
}
Was it helpful?

Solution

You could get all the children elements of subdiv_3 that are <li>. Then iterate through that loop adding the functions as you go.

div = document.getElementById('subdiv_3');
els = div.getElementsByTagName('li');

for (var i=0, len=els.length; i<len; i++) {
    alert(i);  // add your functions here   
}

Looking at your code sample, when you're in the loop creating your functions you may run into closure scoping problems. (All the functions will appear to use the same value of i.) Check out my answer to this question to deal with that problem: How to Add Event Handler with Arguments to an Array of Elements in Javascript?

OTHER TIPS

@Supernovah: You can actually assign a real function to setTimeot(). That rids you of the string formatting, which will stand in your way when you want to do more complex things than just setting one property.

This is the code:

function attachToList() {
  var div = document.getElementById('menu2');
  var els = div.getElementsByTagName('li');
  // create a closure returning an anonymous inner function
  var fn  = function(li) {
    return function() {
      li.style.backgroundColor = "#FFFFCC";
    };
  };
  for (var i=0, len=els.length; i<len; i++) {
    // create function instance suitable for current iteration
    var changeLi = fn(els[i]);
    // pass function reference to setTimeout()
    setTimeout(changeLi, 250*i);
  }
}

And a short explanation:

Using a closure is the trick that makes sure when setTimeout() triggers, all variables still have the expected values.

You do this by writing a function that returns a function. The outer function takes parameters, the inner function does not. But it refers to the parameters of the outer function. In the loop, you call the outer function (with correct parameters) and get a whole new inner function every time, each which has it's own version of the parameter values. This is the one you assign to setTimeout().

In reponse to the comment on Benry's Answer By Benry, After using his code, the following proves that each elementLi can be referred to with els[i]

function attachToList(){
div = document.getElementById('menu2');
els = div.getElementsByTagName('li');
for (var i=0, len=els.length; i<len; i++) {
setTimeout('els['+i+'].style.backgroundColor=\"#FFFFCC\";',(250*i));
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top