1

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?

4
  • It's expected. It's evaluating the selector before the attribute is added and therefore does not match to it. Commented Jun 5, 2013 at 15:04
  • 1
    I can't help thinking that the OP of the original question is doing this wrong... Commented Jun 5, 2013 at 15:05
  • @Cj S. I thought on was meant to be a replacement for live which allowed us to bind to dynamic elements Commented Jun 5, 2013 at 15:06
  • try this way: jsfiddle.net/BjkQT/7 Commented Jun 5, 2013 at 15:06

2 Answers 2

2

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");
});
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.