1

I have a list of divs, that I want to add "onmouseover" events to. I try to iterate over the list of elements, and redefine the "onmouseover" function like this:

for (var i=0; i<3; i++) {
   elements[i].onmouseover = function() { alert('FOO') }; 
}

Unfortunately, after the page finishes loading, it looks like this only gets applied to the very last element. I'm sure this is a real newbie question, but I still haven't figured it out...

Here's a better example exhibiting my problem: http://jsfiddle.net/qajPM/

4
  • 4
    Your assignment is lacking a } at the end.
    – alexn
    Commented Jan 22, 2012 at 0:06
  • Try using jquery, it'll help you a lot.
    – Vyktor
    Commented Jan 22, 2012 at 0:07
  • 1
    Similar code works fine for me here: jsfiddle.net/dqCef How is the elements array created? Is your code in an onload handler, or at the end of the body after all the divs in question?
    – nnnnnn
    Commented Jan 22, 2012 at 0:39
  • @nnnnnn You're right. I added a better example here: jsfiddle.net/qajPM
    – user313724
    Commented Jan 22, 2012 at 1:09

2 Answers 2

2

One thing you can do is instead of assigning an event handler to every div, you could assign one handler to the parent, then simply fetch which div was moused over based on the event target.

HTML:

<div id="parent">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

Javascript:

document.getElementById('parent').onmouseover = function(e) {
    var target = e.target || e.currentTarget;
    alert('Target ' + target.innerHTML + ' was moused over');
};

Fiddle: http://jsfiddle.net/ZhpLA/

As others have pointed out jQuery also makes this have slightly less code (though if this is all you need it for it would be pointless):

$('#parent').on('mouseover', 'div', function(e) {
    alert('Target ' + e.currentTarget.innerHTML + ' was moused over');
});

The advantage to the above jQuery code is that it will apply both to current and future child divs of #parent. If you were to programatically add more the mouseover event would continue to work for them as well.

3
  • jquery is great, but I can't justify importing the library just to solve this one problem.
    – user313724
    Commented Jan 22, 2012 at 0:24
  • Of course, which is why the fiddle is in plain 'ol javascript. ;)
    – T. Stone
    Commented Jan 22, 2012 at 0:25
  • This would work if all divs had the same parent. This isn't the case now, and it's not necessarily a restriction I want to add.
    – user313724
    Commented Jan 22, 2012 at 0:40
1

The problem is that you are creating all of your div elements like this:

parent.innerHTML += "<div> " + i + "</div>"

As I'm sure you know that is equivalent to parent.innerHTML = parent.innerHTML + ..., but the .innerHTML property returns the html as a string (without any already associated event handlers) so each time you do that it is overwriting the entire innerHTML of the parent div with a new string, which means you are effectively adding to the text contents but clobbering the mouseover handlers you've already setup.

Try instead something like this:

var el = document.createElement("div");
el.innerHTML = i;
parent.appendChild(el);

Which appends a new element without affecting the ones already there.

Updated demo: http://jsfiddle.net/qajPM/1/

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.