0

JQuery を使用してリストを動的に作成しており、各要素を「タップ」イベントにバインドしたいと考えています。どうすればいいですか?これは私がやろうとしていることのサンプルですが、うまくいきません。

for(var i=1; i <= 5; i++) {
        var id = "item" + i;
        var li = $("<li data-theme=\"d\" id=\"" + id + "\">Item " + i + "</li>");
        li.appendTo(ul);

        $(document).delegate("#"+id, "tap", function() {
            $("#"+id).attr({ "data-theme" : "e", "class" : "ui-li ui-li-static ui-btn-up-e" });
        });
    }

このコードは、任意の要素をタップするとトリガーされますが、何らかの理由でリストの最後の要素が常に変更されます。

4

3 に答える 3

3

あなたのオプション

  • イベント処理をループの外に移動するか

    for(var i=1; i <= 5; i++) {
     ....
    }
    $(document).delegate("[id^=item]", "tap", function() {
    });
    
  • bindメソッドを使用してtap、 ではなく要素にイベントを適用しますdocument

    for(var i=1; i <= 5; i++) {
      //append li to ul
      $("#"+id).bind("tap", function() {
        $(this).attr({ 
              "data-theme" : "e", 
              "class" : "ui-li ui-li-static ui-btn-up-e"   
        });
      });
    }
    
  • eventしかし、ループの外側に置き、ul後でそれをliに委譲するイベントをバインドするのが最善の方法です。

    for(var i=1; i <= 5; i++) {
     ....
    }
    $("ul").delegate("[id^=item]", "tap", function() {
    });
    

ノート

テーマを変更する場合は、レイアウトも一度更新する必要があります。

$("ul").delegate("[id^=item]", "tap", function() {
     $(this).attr({ 
              "data-theme" : "e", 
              "class" : "ui-li ui-li-static ui-btn-up-e"   
     }).parent("ul").listview().listview("refresh");
});

セレクターSTARTS WITHの使用

これをコードに入れました:

var id = "item" + i;

つまり、5 つの要素のループ全体では、ID は次のようになります。

<li id="item1">..
<li id="item2">..
<li id="item3">..
<li id="item4">..

ここで一般的なことを見ると、次のようになります。

item

したがって、idは で始まるため、 starts with セレクターitemを使用して一般化できます。そう、

id^=item

で始まる ID を持つ要素を検索していることを意味しますitem。属性なので、

[id^=item]

よりモジュラーなアプローチ

この方法には、より少ない HTML が含まれます。

//your ul tag
var ul = $("ul")
//set up an array for adding li to it.
var li = [];
//a temporary element to store "li"
var $li;
for(var i=1; i <= 5; i++) {
    //add required attributes to the element
    var $li = $("<li/>", {
              "data-theme" : "d",
              "id" : "item" + i,
              "html" : "Item " + i
             });
    //push that into array
    li.push($li);
}
//wait for append to finish
ul.append(li).promise().done(function () {
  //wait for list to be added - thats why you wait for done() event in promise()
  //add the click events to this - event delegation - this way your click event is added only once 

  $(this).on("tap", "[id^=item]", function () {
     $(this).attr({ 
              "data-theme" : "e", 
              "class" : "ui-li ui-li-static ui-btn-up-e"   
     }).parent("ul").listview().listview("refresh");
  });

  //then refresh
  $(this).listview().listview("refresh");    
});

このデモは次のとおりです: http://jsfiddle.net/hungerpain/TdHXL/

お役に立てれば!

于 2013-07-09T21:11:11.473 に答える
1

これが私がすることです:

var items = []; // an actual JavaScript array - a list of items.

for(var i=1;i<=5;i++){
    items.push({theme:'d'}); //add an item to our list, 
                             //Anything that actually relates to the item should be
                             //here, text, other data and such. This is our 'view model'.
}

items.forEach(function(item,i){ // for each item, bind to the dom
    var el = document.createElement("li"); //create an element
    el.textContent = i+1; // set its text

    el.onclick = function(e){ // or ontap or whatever
        el.className = "ui-li ui-li-static ui-btn-up-e";
        item.theme = "d";
    }//you mind want to use addEventListener instead at a later point

    item.el = el;
    ul.appendChild(el); // you need access to ul, currently being a jQuery object ul[0].
});

コードからアイテムに直接アクセスできることに注意してください。アイテムを直接更新したり、直接参照したりできます。独自のデータをクエリする必要はありません。データを所有しており、データにアクセスする方法を直接知っています。

また、80kb の依存関係はありません。複雑なセレクターや「魔法の」バインディングはありません。すべてが単純明快で、ただの古い JavaScript です。

注: forEach は、古いブラウザーの場合は (簡単に) shim する必要があります。

于 2013-07-09T21:22:08.687 に答える