2

私はこれを短くしようとします。ユーザーが展開ボタンをクリックしたときに非表示または表示するテキストのボックスを作成しようとしています。私は toggle() メソッドを使用しています。

マークアップは次のようになります。

<span id="toggle0">+</span>
<div id="toggle0Container">
    blablabla...
<div>

<span id="toggle1">+</span>
<div id="toggle1Container">
    blablabla...
<div>

<span id="toggle2">+</span>
<div id="toggle2Container">
    blablabla...
<div>

// etc

#toggle0 は #toggle0Container を切り替え、#toggle1 は #toggle1Container を切り替えます。これはすべて PHP によって生成されるため、これらのコンテナーはいくつでも存在できます。

JQuery コードは次のとおりです。

$(document).ready(function() {
    // array of numbers, it's pretty redundant, there will never be more than 30 containers
    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
    // hide all containers first
    jQuery.each(arr, function() {
        $('#toggle' + this + 'Container').hide();
    });
    // now the toggle buttons
    jQuery.each(arr, function() {
        $('#toggle' + this).click(function() {
            // this line is not working
            $('#toggle' + this + 'Container').slideToggle('slow');
            // and this just changes the toggle button from + to -
            if ($(this).html() == '+') {
                $(this).html('-');
            } else {
                $(this).html('+');
            }
        });
    });
});

トグル部分を除いて機能します(機能しない行の上にコメントを追加しました)。問題はどこですか?

4

8 に答える 8

5

これは、"this" が別のスコープにあり、配列内の数字の 1 つではなく、実際の #toggleN DOM 要素を参照しているためです。

数値の配列を捨てて、次のような別のセレクターを使用することをお勧めします。


$("div[id^=toggle][id$=container]").hide();

$("span[id^=toggle]").click(function() {
     $(this).find("span[id^=toggle][id$=container]").slideToggle("slow");
     // .. do your other html stuff
}

それらのそれぞれを捨てて、トグルセレクターをそれらに置き換えてください。

于 2009-07-16T17:00:00.413 に答える
2

編集

あなたの特定のユースケースにはmgrovesソリューションの方が適していますが、.eachメソッドのパラメーターとしてインデックスと要素を受け入れる方法を説明する回答を残しておきます

元の答え

他の人が言ったように、これの文脈は、あなたがそれを参照している時点であなたが考えているものではありません. Remy Sharp による「 jQuery's this: demystified 」という素晴らしい記事をお読みになることをお勧めします。

.each 関数は、非常に役立つ 2 つのパラメーターを受け入れることができ、その数値の配列は必要ありません。

$('span[id^=toggle']').each(function(idx, elem) {

    // idx is the current index of the jQuery object
    $('#toggle' + idx).click(function() {

        // elem is the current element
        $(elem).next('#toggle' + idx + 'Container').slideToggle('slow');

        if ($(elem).html() == '+') {
            $(elem).html('-');
        } else {
            $(elem).html('+');
        }

    });

});
于 2009-07-16T17:07:03.100 に答える
2

私はmgrovesのアプローチに従いますが、本当に配列のことをしたい場合、または単に each() を適切に使用する方法を理解したい場合は、次のように使用する必要があります。

$(document).ready(function() {
    // array of numbers, it's pretty redundant, there will never be more than 30 containers
    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
    // hide all containers first
    jQuery.each(arr, function(index, item) {
        $('#toggle' + item + 'Container').hide();
    });
    // now the toggle buttons
    jQuery.each(arr, function(index, item) {
        $('#toggle' + item).click(function() {
            // this line is not working
            $('#toggle' + item + 'Container').slideToggle('slow');
            // and this just changes the toggle button from + to -
            if ($(this).html() == '+') {
                $(this).html('-');
            } else {
                $(this).html('+');
            }
        });
    });
});
于 2009-07-16T17:09:23.220 に答える
1

Max がクラスの使用について行ったことを正確に投稿しようとしていました。コンテナーを見つけるためのこの簡単なセレクターを使用して、彼の提案を改善するだけです。

$(function() {
  // hide all containers first
  $(".container").hide();
  // now the toggle buttons
  $(".toggler").click(function() {
    $(this).next().slideToggle("slow");

    if (container.is(":visible")) {
      $(this).html("-");
    }
    else {
      $(this).html("+");
    }
  });
});

スパンのクラスを簡単に取得できない場合は、おそらく $('#SpanContainer>span') のようなものを使用して同様のセレクターを作成し、含まれている要素から派生したタグ名でそれらを選択できます。

于 2009-07-16T17:08:45.373 に答える
1

javascriptを簡素化するために、「トグル」などのトグルボタン(スパン)と「コンテナ」などのトグルコンテナにクラスを配置することをお勧めします。

$(function() {
    // hide all containers first
    $(".container").hide();
    // now the toggle buttons
    $(".toggler").click(function() {
          var container = $("#" + $(this).attr("id") + "Container");
          container.slideToggle("slow");

          $(this).html(container.is(":visible") ? "-" : "+");
    });
});

それを試してみてください。

于 2009-07-16T17:02:36.133 に答える
1

mgroves が言ったように、あなたのスコープは each() を使用することですべてジャッキアップされています。詳細については、これを参照してください。

于 2009-07-16T17:03:58.363 に答える