jquery .on click not working with later added elements

I have the following issue. As far as I know, using .on function should add event listeners to selected elements even though they might not exists at the present time. I am replacing elements on my page and after they are replaced, event listeners are not attached to them. So where did I make mistake?

Here is the code which is not working:

html:

<nav>
    <ul>
        <li>item1</li>
        <li>item2</li>
        <li>item3</li>
    </ul>
</nav>

<button>change</button>

javascript:

$(function() {
    $("ul li").on("click", function() {
        $(this).css({"color": "red"});
    });

    $("button").on("click", function() {
        $("ul li").css({"color": "black"});

        var html = $("nav").html();
        $("nav").html(html);
    });
});

fiddle: http://jsfiddle.net/Q48db/

Upvotes: 1

Views: 766

Answers (4)

Awlad Liton
Awlad Liton

Reputation: 9351

You need delegate.

$("nav").on("click",'ul li', function() {
    $(this).css({"color": "red"});
});

$("button").on("click", function() {
    $("ul li").css({"color": "black"});
                    
    var html = $("nav").html();
    $("nav").html(html);
});

demo fiddle

Upvotes: 0

Felix
Felix

Reputation: 38112

You need to use event delegation for dynamically added element:

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.

$(function () {
    $("nav").on("click", 'li', function () {
        $(this).css({
            "color": "red"
        });
    });

    $("button").on("click", function () {
        $("ul li").css({
            "color": "black"
        });
        var html = $("nav").html();
        $("nav").html(html);
    });
});

Updated Fiddle

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388446

Just using .on() will not make an event handler to work on dynamic elements, you need to use the event delegation format of on()

The format for event delegation is

$(static-ancestor).on(event, dynamic-element-selector, handler)

So

$("nav").on("click", 'li', function () {
    $(this).css({
        "color": "red"
    });
});

Demo: Fiddle

In your case the nav element is the static element because you are changing the its content so you can bind the handler to it and since you want to have the click handler for the li elements pass li as the dynamic element selector

Upvotes: 2

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85653

Use event Delegation method:

$(function() {
    $("ul li").on("click", function() {
        $(this).css({"color": "red"});
    });

    $("document").on("click","button", function() {
        $("ul li").css({"color": "black"});

        var html = $("nav").html();
        $("nav").html(html);
    });
});

Example to understand event delegation:

// attach a directly bound event
$( "#list a" ).on( "click", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});

// attach a delegated event
$( "#list" ).on( "click", "a", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});

Upvotes: 0

Related Questions