0

whileJavascript で -loopを作成しようとしています。

これまでのところ、私はこれを持っています:

<script>
    $(document).ready(function(){       
        var i=0;
        while (i<9999) {
            $(".add_new_item_field" + i).hide();    
        $(".add_new_item_button" + i).click(function(){
            $(".add_new_item_field" + i).slideToggle("slow");
        });
        i++;
        }
    });
</script>

目標は、これを機能させることです:

<div class="add_new_item_button1"></div>
<div class="add_new_item_button2"></div>
<div class="add_new_item_button3"></div>
...
<div class="add_new_item_field1">Show me something</div>
<div class="add_new_item_field2">Show me something</div>
<div class="add_new_item_field3">Show me something</div>
...

しかし、何らかの理由で、それは機能していません。ここで何か不足していますか?

4

4 に答える 4

1

問題は$(".add_new_item_field" + i).slideToggle("slow");、div の 1 つをクリックすると、行の連結が発生することです。それでも、ハンドラーを設定したループはずっと前に実行されており、iすでに の値を持っています9999。これを回避するには、@Davidが示したようにクロージャーを使用してください。

しかし、私はこれが間違ったアプローチだと感じています。10000 個のクリック ハンドラーを設定し、20000 個の jQuery 選択を実行すると、ページが非常に遅くなります。ボタンに 1 つの共通クラスを使用し、フィールドに 1 つの共通クラスを使用します。特定のドキュメントの順序に依存できない場合は、互いに参照する一意の ID を指定しますが、クラスは指定しません。

次に、CSS の 1 行ですべてのフィールドを非表示にし、ボタンのイベント委任を使用して、クリックされたボタンに添付されたデータから ID でフィールドを検索する 1 つの関数を起動します。

<style>
    .add_new_item_field { display:none; }
</style>
<!-- placing the stylesheet here also avoids flickering.
Even better would be of course if it was written dynamically by JS, for not 
hiding the fields in clients that do not support JavaScript -->
<script src=/"jquery.js"></script>
<script>
jQuery(function($) {
    $(document).on("click", ".add_new_item_button", function(e) {
        var id = "field"+$(this).data("field");
        $('#'+id).show();
    });
});
</script>
<div class="add_new_item_button" data-field="1"></div>
<div class="add_new_item_button" data-field="2"></div>
<div class="add_new_item_button" data-field="3"></div>
...
<div class="add_new_item_field" id="field1">Show me something</div>
<div class="add_new_item_field" id="field2">Show me something</div>
<div class="add_new_item_field" id="field3">Show me something</div>
...
于 2012-11-22T14:08:45.197 に答える
1

ハンドラーが実行されると、すでに 9999 に達しているiため、ハンドラーで期待されるものではないと思います。これを修正するには、次のような変数をハンドラー クロージャーに入れる必要があります。i

var i=0;
while (i<9999) {
    $(".add_new_item_field" + i).hide();  
    $(".add_new_item_button" + i).click((function(i) {
        // i is now saved in this closure
        return function() {
            $(".add_new_item_field" + i).slideToggle("slow");
        };
    }(i)));
    i++;
}

補足:これが実際のタスクを解決する最善の方法であるかどうかはわかりませんが、9999 個のイベント ハンドラーをループしてアタッチする必要はないようです...

于 2012-11-22T14:07:50.473 に答える
0

クラスの使い方が間違っていると思います。同じクラスのすべてのオブジェクトにクリックハンドラーを割り当てることができます。ただし、クラス指定子をIDとして使用しようとしており、ハンドラーを各個別のオブジェクトに割り当てようとしています。リンク/URLの動作とレイアウトについても同じことをしませんか?(リンク)あなたは?

これを読んでください:jQuery:クリックハンドラーをクラスに追加して、どの要素がクリックされたかを確認するにはどうすればよいですか?

クラスのハンドラーを設定する場合は、そのクラスとしてdivを指定します。私はクラス指定子をある種のIDとして悪用していません。

于 2012-11-22T14:13:40.830 に答える
-1

クリックハンドラーで、値ではなくi変数をキャプチャするクロージャーを作成しています。これは、すべてのクリック関数に、whileループの最後の変数の値である9999の値が含まれることを意味します。

クリックハンドラーを設定する関数を作成することで修正できます。

var setClick = function(index) {
   $(".add_new_item_button" + index).click(function(){
   $(".add_new_item_field" + index).slideToggle("slow");
   }
}

そして、whileループで使用します。

while (i<9999) {
    $(".add_new_item_field" + i).hide();    
    setClick(i);
    i++;
    }

これで、iの値がクリックハンドラーによって正しくキャプチャされます

于 2012-11-22T14:14:20.203 に答える