Reputation: 5776
I have a button (<a class="gmButton"></a>
) and a <span id="gmToolTip"></span>
, and I'd like the span
to display certain text when the relevant link is mouseovered.
The text to display is an array of strings called toolTips
.
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmToolTip.textContent = null;
clearTimeout(t);
});
When applied to the links one-by-one, the code seems to perform as expected. It's not working when applied in a loop like this. What have I screwed up?
Here's the fiddle: http://jsfiddle.net/d5tpqt5h/1/
Upvotes: 2
Views: 1018
Reputation: 347
Try with innerHTML and closure:
for (var i = 0; i < gmButtons.length; i++){
(function(i) {
gmButtons[i].addEventListener("mouseover", function(){
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.innerHTML = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function(){
gmTooltip.innerHTML = null;
clearTimeout(t);
});
})(i);
}
Upvotes: 0
Reputation: 240968
The issue is that the event listener functions are fired after you have already looped over all of the element. This means that when they are called, i
is equal to 9
(and toolTips[9]
is undefined because the last element's index in an array is one less than its length
).
One option is to wrap the logic in an IIFE in order to capture the current value of i
:
for (var i = 0; i < gmButtons.length; i++) {
(function(i) {
gmButtons[i].addEventListener("mouseover", function() {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
});
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
})(i);
}
Alternately, you could also utilize the .bind()
method in order to pass the current value of i
to the function:
for (var i = 0; i < gmButtons.length; i++) {
gmButtons[i].addEventListener("mouseover", function(i) {
clearTimeout(t);
t = setTimeout(function() {
gmToolTip.textContent = toolTips[i];
}, 500);
}.bind(this, i));
gmButtons[i].addEventListener("mouseout", function() {
gmToolTip.textContent = null;
clearTimeout(t);
});
}
Upvotes: 6
Reputation: 956
Change gmTooltip.textContent = null;
to gmToolTip.textContent = null;
gmTooltip to gmToolTip
Hope it helps!
Upvotes: 1