简体   繁体   中英

Keep event listener on last element of list

I have an un-ordered list with mutiple li elements inside of it. The last element has an on click event listener which adds another li element to the list, seen in this fiddle.

https://jsfiddle.net/45vyLdra/

What I want to do is have the on click event always be on the last element of the list, even after I have appended the new li. Is there a clean way to do this? If I re-run line 2 of

$( document ).ready(function() {
    $("li").last().on("click",function(){
        $("ul").append("<li><a href='#'>Button</a></li>")
    })
})

and just unbind the original event it would work but that seems easier said than done.

The problem you have is that you can't attach an event-handler to an element that doesn't yet exist in the DOM on page load.

As such, you need to hoist the scope, and attach the event handler to an element that's not dynamically generated, delegating the functionality by passing the target element as a parameter of on() .

In this case, you can attach it to the <ul> . You can find the last element with the CSS :last pseudo-selector:

 $(document).ready(function() { $("ul").on("click", "li:last", function() { $("ul").append("<li><a href='#'>Button</a></li>") }) }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> </ul> 

Hope this helps! :)

If the last element could be always the same you might use prepend instead of append . Check it out:

 $(document).ready(function () { $('li').last().on('click', function () { $('ul').prepend('<li><a href="#">Button</a></li>') }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> </ul> 

You might avoid jQuery at all and use Vainilla JavaScript instead:

 document.querySelector('li:last-child').addEventListener('click', () => { const template = document.createElement('template'); template.innerHTML = '<li><a href="#">Button</a></li>'; document.querySelector('ul').prepend(template.content); }); 
 <ul> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> <li><a href="#">Button</a></li> </ul> 

Note: In this example I'm using arrow functions (an ES6 feature)

Add the listener to the ul and check if it's the last child that was clicked before adding the new item.

 var growingList = document.getElementById('the-list'); growingList.addEventListener('click', addToList, false); function addToList(event) { event = event || window.event; var theList = document.getElementById('the-list'); var listItems = theList.children; var lastItem = listItems.length - 1; if (event.target === listItems[lastItem]) { var htmlToAdd = '<li>' + (lastItem + 2) + '</li>'; theList.insertAdjacentHTML('beforeend', htmlToAdd); } } 
 <ul id="the-list"> <li>1</li> <li>2</li> <li>3</li> </ul> 

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