简体   繁体   中英

jQuery: last doesn't work with mixed tags

I am having html look like below:

<td id="sample">
    <select>
        <option>
    </select>
    <br/>
    <select>
        <option>
    </select>
    <br/>
//...
</td>

I know we should be using div instead of table but our whole webpage is designed this way and it is kind of time-consuming to change it.

What I am trying to do is add a event handler to the change of last select tag. I have tried: $("#sample > select:last") and $("#sample").find("select).last() but both of them tend to find the last select before br tag which means the first one. I can probably solve this issue with adding an attribute in my code but that will result in adding a global variable and an amount of code. Is there a cleaner solution?

Edit: Sorry that I didn't understand my issue correctly and many thanks to all the comments. I guess my issue actually is I put the event handler in my document ready section and append more <select> in that event handler. So every time when I am trying to trigger the event, it always come to the original last element.

My code looks like:

$('#sample > select:last').on('change', function() {
    $('#sample > select:first').clone().show().appendTo('#sample');
    $("<br/>").appendTo('#sample');
});

But although I kind of find the reason, I am still confused in solving it. Is there any solutions around this?

You're dynamically creating your elements, therefore you need a dynamic event delegation:

Dynamic Delegation works like:

 $("staticElement").on("someevent", "dynamicElement", function)

and it's used to attach an event to the parent with a renewal look for recently appended child Elements.
To explain, on execution time if you attach an event to some elements directly like: $(".foo").click(fn) or $(".foo").on("click", fn) it will not account for .foo elements added in a later time cause they were not in the .foo collection at the time.
By assigning the event to the static parent, the event Delegation will bubble inversely searching for children (that match the selector argument and are the initiators of the same event trough event.target ) that received that event.

In your example:

// static Parent // evt ,    dynamic 
$("#sample").on("change",   "> select:last",   function() {
    $('#sample > select:first').clone().show().appendTo('#sample');
    $("<br/>").appendTo('#sample');
});

More details to your question here: http://api.jquery.com/on/#direct-and-delegated-events

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