2

多くのセルを含む HTML テーブルがあり、各セルにクラスまたは ID を与えて、対応するサウンドを再生できるようにしたいと考えています。セルが多いので、Javascript+jQuery でこのタスクを自動化し、HTML の乱雑さを減らしたいと考えています。

したがって、テキストが含まれるセルがあるとしますa。そのセルのクラスをに設定し、サウンドを再生するIDをclick_sound_a持つタグを生成します。(セルに ID を使用することもできますが、いくつかの重複があると思います。)<audio>sound_aa.mp3

例として、5 つのサウンドを含む次のコードがあります。

<script type="text/Javascript">
 // trigger play event on an audio element
function playSound(sound) {
    $("#sound_"+sound).get(0).play();
}

$(document).ready(function() {
    var sounds = ["a", "i", "u", "e", "o"];

    // create HTML5 <audio> elements
    for (var i in sounds) {
        $("<audio id='sound_"+sounds[i]+"'>  <source src='/downloads/sounds/"+sounds[i]+".mp3' type='audio/mpeg'> </audio>").appendTo("#page");

        // make columns clickable to play sounds
        $(".click_sound_"+sounds[i]).click(function() {
            playSound(sounds[i]);
        });
    } // end for
});
</script>

問題は、ループが終了すると、正しいクラスが割り当てられていても、すべてのセルが最後の要素のサウンドを取得することです。したがって、この場合、すべてのセルが再生されo.mp3ます。バグはどこですか?

4

1 に答える 1

1
<script type="text/Javascript">
 // trigger play event on an audio element
function playSound(sound) {
  return function() {
    $("#sound_"+sound).get(0).play();
  }
}

$(document).ready(function() {
    var sounds = ["a", "i", "u", "e", "o"];

    // create HTML5 <audio> elements
    for (var i in sounds) {
        $("<audio id='sound_"+sounds[i]+"'>  <source src='/downloads/sounds/"+sounds[i]+".mp3' type='audio/mpeg'> </audio>").appendTo("#page");

        // make columns clickable to play sounds
        $(".click_sound_"+sounds[i]).click(playSound(sounds[i]));
    } // end for
});
</script>

説明: これは JavaScript の典型的な落とし穴です。定義したイベント ハンドラーが呼び出されるたびに、i最後に 4 で更新された変数の値が検索されます。クロージャーを使用して、適切な値をイベント ハンドラーにバインドする必要があります。

実際、これは Crockford の著書「 Closure in The Good Parts」とほぼ同じ例です。

于 2013-06-03T18:47:54.903 に答える