简体   繁体   中英

jQuery won't bind click to underscore template using .on() for items added via function

I'm using underscore to create some elements and appending them to a div with jQuery.

At the bottom of the page I'm using jQuery's .on() to respond to clicks on the elements.

$('.pickup').on('click',
    function(e) {
        alert("hello");
    }
);

Via some user interaction (in Google maps), I've got to add more elements to the div and want them to respond to clicks as well. For some reason they do not. I've pared it all down on jsfiddle:

http://jsfiddle.net/thunderrabbit/3GvPX/

When the page loads, note that clicking on the lines in output will alert('hello') via jQuery.

But click the [add] button and the new lines do not respond to clicks.

My HTML

<div id="unit_2225" class="pickup">
    <span>Click me; I was here first</span>
</div>
<script type="text/template" id="unit-template">
    <div class="unit-item">
        <span class="pickup">
            <span>click us (<%= unit_id %>) via underscore</span>
        </span>
    </div>
</script>
<div id="divID">
</div>
<button>add</button>

My Javascript

var addUnitToDiv = function(key,val) {
    console.log(val);
    var template = _.template($('#unit-template').html(),val);
    $('#divID').append(template);
}

var unit_ids = [{unit_id:'hello'},
                {unit_id:'click'},
                {unit_id:'us'},
                {unit_id:'too'},
                {unit_id:112}];

$.each(unit_ids, addUnitToDiv);

var unit_pids = [{unit_id:'we'},
                 {unit_id:'wont'},
                 {unit_id:'respond'},
                 {unit_id:'to'},
                 {unit_id:'clicks'},
                 {unit_id:358}];

createMore = function() {
    $.each(unit_pids, addUnitToDiv);
}

$('.pickup').on('click','span',function() {
    alert("hello");
});

$('button').click(createMore);

I found a similarly worded question but couldn't figure out how to apply its answer here.

Instead of binding events directly to the elements, bind one event to their container element, and delegate it:

$("#divID").on("click", ".pickup", function () {
    // Your event handler code
});

DEMO: http://jsfiddle.net/3GvPX/3/


In this case, the event handler is only executed for elements inside of the container #divID that have the class "pickup" .

And in your scenario, the elements are being added to the element with an id of "divID". Thus, where the two selectors came from.

This is handy because, as you've found out, dynamically adding elements doesn't magically bind event handlers; event handlers bound normally with .on() are only executed (bound) on those present at the time of binding .

It could even help if you change the delegated selector to "span.pickup" (if you know the elements will always be a <span> like in your template), so that the DOM is filtered by the tag name first.


Reference:

Working demo http://jsfiddle.net/u2KjJ/

http://api.jquery.com/on/

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. You can attach the handler on the document level.

Hope it fits the need, :)

code try the code changed below

$(document).on('click','.pickup',function() {
    alert("hello");
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM