0

What this code does is create a paragraph with whatever the value of #paragraph is which is a textarea tag and it works perfectly fine.

$('#insert_paragraph').click(function(){
  var text = $('#paragraph').val();
  $('#container').append('<p>'+text+'</p>');
});

And this code simply adds a class to whatever p tag was clicked on, however it only adds this class to the p elements that were created the first time the page was rendered and not the p elements created with the code above.

$('p').click(function(){
  $(this).addClass('box');
});
Manuel Medina
  • 329
  • 1
  • 4
  • 14
  • 1
    Because they didn't exist when the original elements were selected. http://learn.jquery.com/events/event-delegation/ – Kevin B May 06 '13 at 21:45
  • possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Blazemonger May 06 '13 at 21:46

2 Answers2

4

When you do $('p'), jQuery goes out and finds the p elements that exist at that point in time. So you're hooking up a handler only to those, not to others added later.

You can use event delegation, which watches for clicks on an ancestor element, and then checks to see if they match a selector. For instance, the following hooks click on the document but only fires if the click passed through a p element, and so it doesn't care when the p elements are created (provided nothing else has hooked the event higher up and stops it bubbling):

$(document).on('click', 'p', function(){
//^             ^        ^ --- the selector to filter against
//|             +--- the event to hook
//+--- the element to hook it on
  $(this).addClass('box');
});
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
1

T.J is exactly right. You are binding the event to all existing paragraphs. After that, any additional paragraph tags created will have no events bound to them.

The code below combines your events, binding the paragraph click event right after the paragraph is added. You will still need to bind all existing paragraphs after the page loads as you were doing.

$('#insert_paragraph').click(function(){
    var text = $('#paragraph').val();
    $('#container').append('<p>'+text+'</p>');

     //Bind Event to last paragraph (the one just added)
     $('#container p:last-child').click(function(){
         $(this).addClass('box');
     });
});
ejc
  • 333
  • 2
  • 7