【问题标题】:Append <li> element to <ul> and add click event for each?将 <li> 元素附加到 <ul> 并为每个元素添加点击事件?
【发布时间】:2011-05-24 14:03:35
【问题描述】:

我想以编程方式将一系列&lt;li&gt; 元素添加到&lt;ul&gt;,并为每个元素添加一个点击事件。

我不知道该怎么做,至少不是以简洁的 jQueryish 方式。

这是我现有的代码:

<ul id="saved-list"></ul>
<script type="text/javascript">
$.each(all_objects, function() {{
    var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
    $('#saved-list').append(list_route);      
    // add unique id (this.id) to item and click event here?
    // pseudocode - onclick: alert(this.id);
});
$('#saved-list').refresh('listview'); // jquery mobile list refresh
</script>

请有人建议如何以编程方式向每个列表项添加点击事件?

更新:我需要为每个列表项做一些稍微不同的事情(我们只是说一个警报) - 很抱歉没有说清楚。

【问题讨论】:

  • 您的 ul id 属性缺少引号,并且脚本周围没有脚本块。复制/粘贴错误?
  • @jvenema,谢谢,已编辑!

标签: javascript jquery jquery-mobile


【解决方案1】:

您最好使用.live().delegate(),而不是担心在您创建的每个元素上创建.click() 处理程序。像这样的:

$('#saved-list').delegate('li', 'click', function () {
    // do stuff on click
});

您只需绑定此点击侦听器一次,它将适用于 ID 为 saved-list 的元素的后代的每个 &lt;li&gt;


如果您确实想为每个 &lt;li&gt; 创建单独的点击处理程序(但我不推荐这样做),这是一个不错的方法:

$.each(all_objects, function() {
    var $a = $('<a/>', {
        href: '#saved-route',
        text: this.text
    });

    var $li = $('<li/>', {
        click: function () {
            // do stuff on click
        }
    }).append($a);

    $('#saved-list').append($li);
});

【讨论】:

  • 对不起,我没有说清楚,我需要为每个 li 元素做一些不同的事情。 (已更新qu。)
  • 看起来不错,谢谢。出于兴趣,您为什么不建议为每个列表元素创建单独的点击处理程序?
  • @phil 在使用.live().delegate() 时不一定有问题。根据被点击的元素,点击处理函数的行为会有所不同。
  • 我通常更喜欢使用.live().delegate() 而不是.bind()(或其等价物)来尽量减少事件监听器的数量。许多事件侦听器可能会开始阻塞页面,尤其是在较旧的浏览器中。见stackoverflow.com/questions/2629803stackoverflow.com/questions/4782399
  • 如果您在许多元素上的特定事件(或事件集)上执行完全相同的逻辑,那么在某个共同祖先上创建单个事件侦听器只是更轻量级,而不是创建一个您感兴趣的每个元素上的监听器。此外,由于 .live().delegate() 在一个共同的祖先上,您不必担心将监听器重新绑定到添加的元素。这是另一个重大胜利,绝对适用于您的情况。
【解决方案2】:

不要。

与其为每个元素绑定一个新的事件处理程序(这可能会变得非常昂贵),不如将一个事件处理程序绑定到#saved-list,这是一个共同的祖先。事件冒泡意味着祖先元素会收到关于其后代事件的通知,因此您可以在那里处理事件而不是原始元素。

这样的……

$.each(all_objects, function() {{
    var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
    $('#saved-list').append(list_route);      
});
$('#saved-list').delegate('li', 'click', function() {
    // do something here each time a descendant li is clicked
});

delegate

【讨论】:

    【解决方案3】:

    @Matt Ball 非常接近这里的答案,但我会更清楚地补充一点,您可以根据单击的元素对代理执行不同的操作:

    <ul id="saved-list"></ul>
    <script type="text/javascript">
    var $savedList = $("#saved-list");
    $.each(all_objects, function() {
        $savedList.append("<li><a href='#saved-route'>" + this.text + "</a></li>");
    });
    $savedList.delegate("li", "click", function (e) {
        alert($(this).text());
    });
    

    $('#saved-list').refresh('listview'); // jquery移动列表刷新

    请注意,在委托中this 仍然指的是被点击的li

    【讨论】:

      【解决方案4】:

      在当前循环中(或之后)添加它还不够吗?

      $('#saved-list li').click(function(){ alert('hello'); });

      【讨论】:

        【解决方案5】:

        您可以使用live 函数,但缺点是您可能需要某种机制来准确确定哪些li 项目已被点击:

        $("#saved-list li").live('click', function() {
            //act on click
        });
        

        【讨论】:

          【解决方案6】:

          hello phil 在 jquery 中,您可以创建 dom 对象,而无需将它们作为文本添加到 dom 中。 这将为您提供在添加之前(以及之后)操作它们的机会。

          $("<li />")
            .append(
              $("<a />")
               .attr("href" ,"#saved-route")
               .text(this.text))
            .click(function() {
              // your click event
            })
            .appendTo("#saved-list");
          

          【讨论】:

          • 不对,您将href 属性添加到&lt;li&gt; 上,但根本没有创建&lt;a&gt;
          【解决方案7】:
          $.each(all_objects, function() {{
              var list_route = "<li><a href='#saved-route'>" + this.text + "</a></li>";
              var newLi = $(list_route);
              newLi.click( function(){} ).attr("id","foo");
              //if you want the a
              newLi.find("a").click( function(){} ).attr("id","foo");
          
              $('#saved-list').append(newLi);              
          });
          

          【讨论】:

            【解决方案8】:

            .click 函数将点击处理函数绑定到任何给定元素。正如代码中的 cmets 所述,您可以在项目被 DOM 化后使用 ID 或其他方式来选择项目,但另一种方法是简单地引用包含要绑定的元素的变量。

            例子:

            var li = $('<li />');
            li.click(function() { ... });
            

            这可能有点风格,但 jQuery 的特性之一是它是可链接的。这意味着 jQuery 函数调用总是返回对 jQuery 本身的包装集的引用。使用可链接方面,您可以像这样重写上面的代码:

            var list = $('#saved-list'); $.each(all_objects, function(i, item) {{
                list.append(
                    $('<li />')
                        .append(
                            $('<a />').text(item.text)
                        )
                        .click(function() { ... } );
                );
            });
            

            【讨论】:

              【解决方案9】:

              虽然我不知道这个$('#saved-list').refresh('listview') 业务是关于什么的,但您可能正在寻找以下内容:

              var listItemEls = all_objects.map(function () {
                  return $('<li id="' + this.id + '"><a href="#saved-route">' + this.text + '</a></li>')
                         .click(function (e) {
                             // do whatever here
                         })
                         .get();
              });
              
              $('#saved-list').append(listItemEls);
              

              请注意,我们避免在最后一刻才追加到 DOM,因为追加成本很高。

              正如其他发帖者所提到的,通常使用委托点击处理程序是一种更好的方法。那看起来像

              var listItemEls = all_objects.map(function () {
                  return $('<li id="' + this.id + '"><a href="#saved-route">' + this.text + '</a></li>')
                         .get();
              });
              
              $('#saved-list').append(listItemEls)
                              .delegate("li", "click", function (e) {
                                  // do stuff here.
                              });
              

              【讨论】:

                【解决方案10】:

                这就是bind 存在的原因。

                $.each(all_objects, function(index) {{
                    $("#saved-list").append("<li id='item" + index + "'><a href='#saved-route'>" + this.text + "</a></li>");
                    $("#saved-list li").bind("click", function() {
                        alert("Clicked on " + this.id);
                    });
                });
                

                此外,这种方式很容易为每个项目创建不同的点击:

                $("#saved-list li#item1").bind(...)
                $("#saved-list li#item2").bind(...)
                $("#saved-list li#item3").bind(...)
                

                【讨论】:

                • .bind('click', ...).click(...) 相同。
                • 没问题;只是指出它,因为.click() 更简洁。
                猜你喜欢
                • 1970-01-01
                • 2013-04-30
                • 2013-05-27
                • 2022-11-03
                • 2016-10-31
                • 1970-01-01
                • 1970-01-01
                • 2013-03-16
                • 1970-01-01
                相关资源
                最近更新 更多