2013-07-09 92 views
0

我使用JQuery动态创建列表,并希望将每个元素绑定到“tap”事件。我将如何做到这一点?这是我正在尝试做的一个示例,但它不起作用。将事件绑定到列表元素

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" }); 
     }); 
    } 

窃听的任何元素时,该代码会触发,但它始终修改列表因为某些原因最后一个元素。

+1

我有一个简单的问题。你已经自己创建了这些项目。你有他们的参考。你为什么要添加'data-theme'并设置'id'?您可以创建一个对象数组来备份数据,然后让它们引用这些元素。这样,你可以很好地分离关注点,而且你不需要所有这种巫术。 –

+0

呃这个问题很好,我的代码有点傻,因为我现在只是搞乱了。我添加了数据主题,因为我想在点击它时更改列表元素的颜色。 – user2066880

+1

数据属性是一个可怕的特征,通过滥用没有听说过关注点分离的人来推动规范。坏习惯很难打破 - 我强烈建议你学习第一次做对。你有兴趣看到一个不使用数据属性或jQuery的替代设计作为完成同样事情的答案吗? –

回答

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稍后将其委托给力。

    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 SELECTOR

你把这个在你的代码:

var id = "item" + i; 

这意味着5种元素的整个循环,你的ID是要这个样子的:

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

在COM展望周一在这里的事情,我会说这是:

item 

所以,既然你的IDS开始item你可以通过使用starts with selector概括它。因此,

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/

希望这有助于!

+0

好的答案,这个工作完美!你介意解释在[ID * =项目]选择是如何工作的?我从来没见过像格式与方括号和* =运算符。 – user2066880

+0

@ user2066880检查答案现在 – krishgopinath

+0

谢谢老板,你的答案肯定帮我最! – user2066880

1

只需将事件处理程序移至for循环之外即可。

而更换

$(document).delegate("#"+id, "tap", function() { 

$(document).delegate("[id*=item], "tap", function() { 

JS

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*=item]", "tap", function() { 
    $("#" + id).attr({ 
     "data-theme": "e", 
      "class": "ui-li ui-li-static ui-btn-up-e" 
    }); 
}); 
+0

你是一个巫师!非常感谢。你介意解释第一个参数“”[id * = item]“是如何工作的? – user2066880

+0

从jQuery 1.7开始,.delegate()已经被.on()方法取代。 –

+0

它是属性包含选择器。匹配id属性中包含'item'的所有​​元素..检查这个..检查这个http://api.jquery.com/attribute-contains-selector/ –

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对旧版浏览器(容易)被垫高。

+0

我有一种感觉,你不明白jQM是如何工作的.. – krishgopinath

相关问题