Jason
Jason

Reputation: 15931

jquery select element based on attribute added dynamically

I was trying to answer this question: Find specific anchor tag and replace data atribute on click and I created this jsfiddle which attempts to select an anchor element based on a data attribute.

I want to trap events on this anchor based on specific data attributes.

<a href="#" class="article-play" data-play="4">click</a>

JS

//this event only fires if 'data-pause' is initially specified in the anchor element
$(".article-play[data-pause]").on("click", function() {
    $(this).removeAttr("data-pause");
    $(this).attr("data-play",4);

    $("#output").text("playing 4");
});

//this event only fires if 'data-play' is initially specified in the anchor element
$(".article-play[data-play]").on("click", function() {
    $(this).removeAttr("data-play");
    $(this).attr("data-pause",3);

    $("#output").text("pausing 3");
});

Is this expected behavior? A bug in jQuery? Something else?

Upvotes: 1

Views: 2161

Answers (2)

A. Wolff
A. Wolff

Reputation: 74410

Because your element is not in DOM at time you bind handler, you need to delegate event:

http://jsfiddle.net/BjkQT/8/

$(".article").on("click", ".article-play[data-pause]", function () {
    $(this).removeAttr("data-pause");
    $(this).attr("data-play", 4);

    $("#output").text("playing 4");
});

$(".article").on("click", ".article-play[data-play]", function () {
    $(this).removeAttr("data-play");
    $(this).attr("data-pause", 3);

    $("#output").text("pausing 3");
});

Upvotes: 2

wirey00
wirey00

Reputation: 33661

You need to use delegation if you are dynamically changing the element

$('parentelement').on('click','.article-play[data-pause]',function(){
    $(this).removeAttr("data-pause");
    $(this).attr("data-play",4);

    $("#output").text("playing 4");
});

$('parentelement').on('click','.article-play[data-play]',function(){
    $(this).removeAttr("data-play");
    $(this).attr("data-pause",3);

    $("#output").text("pausing 3");
});

jQuery live documents the replacement for .live()

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

It shows binding to the document as that's how live works - but it's better to bind the handler to a static parent element of the selector

You can read more about it here in the jQuery .on() documentation

Upvotes: 1

Related Questions