0

私はこのコードを書きましたが、機能しません:

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>

開始するidと、bucleにさまざまなsが表示されますが、私がaを実行するmouseoverと、サイズに変更はありません。

4

5 に答える 5

2

なぜそれが機能しないのか

コードが機能しない理由は次のとおりです。

iすぐに実行されるコード(showおよびhover呼び出しなど)の正しい値が含まれます。ただし、JavaScriptの動作方法により、これはコールバック(に指定したものなど)では機能しませんhover。JavaScriptは、コールバックが提供されたときの変数のではなく、変数を記憶します。ループが完了するまで、コールバックは呼び出されません。そのため、コールバックでは常に5になります。これは、の最後の値であるためです。ii

あなたはここでそれについてもっと読むことができます:クロージャ(MDN)

また、は一意である必要がidあることに注意してください。id5つの異なる要素に「メニュー」を与えることはできません。それがクラスの目的です。言い換えれば、あなたはあなたのコードidclass逆行しているのです。

それを機能させる方法

クロージャの「問題」を回避する最も簡単な方法は$(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つは機能します。きちんとね?

于 2012-08-02T19:06:38.883 に答える
1

これを使ってみてください

$(function(){

    var menu_h_number=5;

    for (var i=1; i <= menu_h_number;i++) {
        $(".web_header_mb_"+i).show(1000)
                              .css("background","#FF0000")
                              .mouseover(function () {
                                  $(this).css("width","200");
                              })
                              .mouseout(function () {
                                  $(this).css("width","300");
                              });
    }
});

jsfiddleでも利用可能

于 2012-08-02T18:20:50.843 に答える
1

これは、i変数がスコープ内にないか、ホバーコードの実行時に最新の値を持っているためです。代わりに、この変数を使用してください。

Fyi:1. divタグのIDは同じですが、クラス名が異なります。代わりに、それらを同じクラスと異なるIDにします。あなたがjQuery.each関数を非常にうまく利用することができるより。

  1. ホバー関数には2つの引数を指定できます。1つ目はmousein用、2つ目はmouseout用です。そうすれば、コードを簡潔にすることができます
于 2012-08-02T18:20:56.427 に答える
1

jQuery.hover()は、実際にはマウスインとマウスアウトの2つの引数を取ります。

$(".web_header_mb_"+i).hover(
function ()  { $(this).css("width","200px") }, 
function ()  { $(this).css("width","300px") }
);

実際、コードを見ると、それは実際には良い方法ではありません。ここで、この方法を試してください。forループで反復する代わりに、すべてのdivに同じクラスを与え、$。eachを使用して目的のイベントを指定します。

<div id="menu" class="web_header_mb"></div>
<div id="menu" class="web_header_mb"></div>
<div id="menu" class="web_header_mb"></div>
<div id="menu" class="web_header_mb"></div>
<div id="menu" class="web_header_mb"></div>

$.each(".web_header_mb", function (){
  $(this).hover(
   function ()  { $(this).css("width","200px") }, 
   function ()  { $(this).css("width","300px") }
  );
});
于 2012-08-02T18:24:11.000 に答える
1

要素をループする必要はありません。セレクターを理解するだけで、jQueryがループします。

で始まるクラスを持つすべての要素を照合してから、web_header_mb_不要な要素を削除してみてください。それらが正しいインデックスを持っている場合は、:lt(5)またはslice(0,5)、そうでない場合は、クラスの最後の文字に基づいてそれらをフィルタリングする必要があります。メソッドをチェーンすることもできます。毎回セレクターを呼び出す必要はありません。

$("[class^='web_header_mb_']").filter(function() {
    var C = $(this).prop('class'); 
        C = C.charAt(C.length-1);
    return (C==1||C==2||C==3||C==4||C==5);
}).show(1000)
  .css("background","#FF0000")
  .on('mouseenter mouseleave', function() {
        $(this).css('width', e.type==='mouseenter'?'200':300);
});

また

$("[class^='web_header_mb_']:lt(5)").show(1000)
    .css("background","#FF0000")
    .on('mouseenter mouseleave', function() {
       $(this).css('width', e.type==='mouseenter'?'200':300);
});
于 2012-08-02T18:42:30.320 に答える