なぜそれが機能しないのか
コードが機能しない理由は次のとおりです。
i
すぐに実行されるコード(show
およびhover
呼び出しなど)の正しい値が含まれます。ただし、JavaScriptの動作方法により、これはコールバック(に指定したものなど)では機能しませんhover
。JavaScriptは、コールバックが提供されたときの変数の値ではなく、変数を記憶します。ループが完了するまで、コールバックは呼び出されません。そのため、コールバックでは常に5になります。これは、の最後の値であるためです。i
i
あなたはここでそれについてもっと読むことができます:クロージャ(MDN)
また、は一意である必要がid
あることに注意してください。id
5つの異なる要素に「メニュー」を与えることはできません。それがクラスの目的です。言い換えれば、あなたはあなたのコードid
にclass
逆行しているのです。
それを機能させる方法
クロージャの「問題」を回避する最も簡単な方法は$(this)
、コールバック関数内で使用することです。jQueryでは、this
コールバック関数内のキーワードは常にイベントをトリガーしたオブジェクトを指します。使用$(this)
することで、大騒ぎすることなく、正確に正しいjQueryオブジェクトを手に入れることができます。
for (i=1; i<=menu_h_number; i++)
{
var currentItem = $(".web_header_mb_" + i);
currentItem
.show(1000)
.css("background", "#FF0000");
.hover(
function() { // mouseenter
$(this).css("width", 200); // <--
},
function() { // mouseleave
$(this).css("width", 300); // <--
});
}
上記のコードで行ったもう1つのことは、jQueryオブジェクトをローカル変数( )にバッファリングcurrentItem
することです。これにより、要素を1回(この場合は6回ではなく)検索するだけで済むため、コードが高速になります。可能な限りこれを行う必要があります。
また、ご覧のとおり、このhover
関数はmouseover
イベント専用ではありません。mouseover
との両方を処理するためのコールバックを与えることができますmouseout
。
他の人がすでに示唆しているように、あなたができるもう1つのことは、5つの異なるクラスの代わりに単一のクラスを使用することです。クエリが複数のオブジェクトに一致する場合、jQuery関数($()
)は実際にコレクションを返します。
したがって、次のHTMLが与えられます。
<div class="menu web_header_mb"></div>
<div class="menu web_header_mb"></div>
<div class="menu web_header_mb"></div>
<div class="menu web_header_mb"></div>
<div class="menu web_header_mb"></div>
次のように、each()を使用できます。
$(".menu.web_header_mb").each(function() {
$(this)
.show(1000)
.css("background", "#FF0000");
.hover(
function() { // mouseenter
$(this).css("width", 200);
},
function() { // mouseleave
$(this).css("width", 300);
});
});
またはこれさえ:
$(".menu.web_header_mb").
.show(1000)
.css("background", "#FF0000");
.hover(
function() { // mouseenter
$(this).css("width", 200);
},
function() { // mouseleave
$(this).css("width", 300);
});
show()、css()、hover()はすべてjQueryコレクション(および単一のjQueryオブジェクト)で機能するため、最後の1つは機能します。きちんとね?