Append
  • element to
      and add click event fo
  • 2020-06-17 14:28发布

    I'd like to add a series of <li> elements to a <ul>, and add a click event to each one, programmatically.

    I'm not sure how to do this, at least not in a neat, jQueryish way.

    This is my existing code:

    <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>
    

    Please could someone advise how to add a click event to each list item programmatically?

    UPDATE: I need to do something slightly different for each list item (let's just say an alert) - apologies for not making this clear.

    10条回答
    成全新的幸福
    2楼-- · 2020-06-17 14:58

    Isn't it enough to add this in (or after) your current loop?

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

    查看更多
    一纸荒年 Trace。
    3楼-- · 2020-06-17 15:00

    @Matt Ball is pretty close to the answer here, but I will add a little more clearly that you can do different things with the delegate depending on what element was clicked:

    <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 mobile list refresh

    Note that in the delegate this is still referring to the li that was clicked on.

    查看更多
    再贱就再见
    4楼-- · 2020-06-17 15:01

    Although I don't know what this $('#saved-list').refresh('listview') business is about, the following might be what you're looking for:

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

    Note that we avoid appending to the DOM until the last minute, because appending is expensive.

    As other posters mention, using a delegated click handler is a better approach, generally. That would look something like

    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.
                    });
    
    查看更多
    我想做一个坏孩纸
    5楼-- · 2020-06-17 15:06

    Don't.

    Rather than binding a new event handler for each element (which could become quite expensive), bind a single event handler to #saved-list, which is a common ancestor. Event bubbling means that ancestor elements are notified of events on their descendants, so you can handle events there instead of on the originating element.

    Something like this...

    $.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
    });
    

    See delegate

    查看更多
    Evening l夕情丶
    6楼-- · 2020-06-17 15:06

    You could use the live function, the downfall is that you might need some mechanism to determine exactly which of the li items that have been clicked:

    $("#saved-list li").live('click', function() {
        //act on click
    });
    
    查看更多
    一纸荒年 Trace。
    7楼-- · 2020-06-17 15:13

    This is why bind exists.

    $.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);
        });
    });
    

    Also, this way is very easy to create different clicks for each item:

    $("#saved-list li#item1").bind(...)
    $("#saved-list li#item2").bind(...)
    $("#saved-list li#item3").bind(...)
    
    查看更多
    登录 后发表回答