I wrote this code but it doesn’t work:
JavaScript:
$(function() {
var menu_h_number=5
for (i=1; i<=menu_h_number; i++)
{
$(".web_header_mb_"+i).show(1000);
$(".web_header_mb_"+i).css("background", "#FF0000");
$(".web_header_mb_"+i).hover(function ()
{
$(".web_header_mb_"+i).css("width", "200");
});
$(".web_header_mb_"+i).mouseout(function ()
{
$(".web_header_mb_"+i).css("width", "300");
});
}
});
HTML:
<div id="menu" class="web_header_mb_1"></div>
<div id="menu" class="web_header_mb_2"></div>
<div id="menu" class="web_header_mb_3"></div>
<div id="menu" class="web_header_mb_4"></div>
<div id="menu" class="web_header_mb_5"></div>
When start show different ids in the bucle but when I do a mouseover, there’s no change to the size.
Why it doesn’t work
The reason your code doesn’t work is this:
iwill have the correct value for code that is executed immediately (e.g. theshowandhovercalls). But, because of the way JavaScript works, this doesn’t work for callback (such as the one you give tohover). JavaScript will remember the variable, not the value of the variable at the time the callback was provided. The callback won’t be called until after the loop is completed. That’s why in the callbacksiwill always be 5, because that wasi‘s last value.You can read more about that here: Closures (MDN)
Also, be aware that
id‘s must be unique. You can’t give theid“menu” to five different elements; that’s what classes are for. In other words: you’ve gotidandclassbackwards in your code.How to make it work
The easiest way to circumvent the closure “problem” is to use
$(this)inside the callback functions. In jQuery, thethiskeyword inside a callback function always points to the object which triggered the event. By using$(this)you have exactly the right jQuery object, without any fuss:Another thing I did in the code above is buffer the jQuery object in a local variable (
currentItem). This makes your code faster, because you only have to look up the element once (instead of 6 times, in this case). You should do this as much as possible.Also, as you can see, the
hoverfunction isn’t just for themouseoverevent. You can give it callbacks to handle bothmouseoverandmouseout.One other thing you could do, as others have already suggested, is use a single class instead of 5 different classes. The jQuery function (
$()) will actually return a collection if the query matches more than one object.So, given the following HTML:
You could use each(), like this:
Or even this:
That last one works because show(), css() and hover() all work on jQuery collections (as well as single jQuery objects). Neat, huh?