Reputation: 53806
When I click the 'Show' button the show listener is invoked and a new hide button is displayed. But why is the hide button not invoked when I then click 'Hide' ?
$('.myCss').append('<input type="button" class="show" value="Show"/>');
$('.show').on('click', function () {
console.log('show clicked');
$('.myCss').append('<input type="button" class="hide" value="Hide"/>');
});
$('.hide').on('click', function () {
console.log('hide clicked');
$('.myCss').append('<input type="button" class="show" value="Show"/>');
});
Upvotes: 1
Views: 2013
Reputation: 436
Several people have correctly answered that the hide button is created after the event is bound to the controls. I suggest a different approach of using a handler at a higher level (document, in my example) that will attach to future controls (the current approach to the now deprecated .live).
Example: http://jsfiddle.net/kQ2JA/1/
This will better match your expectations of binding the event to all current and future controls.
Upvotes: 0
Reputation: 1679
Because when you set the event, the .hide element doesn't exist. You could try setting the events like:
$('.myCss').append('<input type="button" class="show" value="Show"/>');
$('.myCss').on('click', '.show', function () {
console.log('show clicked');
$('.myCss').append('<input type="button" class="hide" value="Hide"/>');
});
$('.myCss').on('click', '.hide', function () {
console.log('hide clicked');
$('.myCss').append('<input type="button" class="show" value="Show"/>');
});
This attaches the click to the .myCss element (shich always exists), but only fires the function when the click was fired on .hide element inside it.
This solution is more efficent that creating the event everytime the element is created.
Upvotes: 1
Reputation: 4203
When the '.hide' event handler is created, the 'Hide' button doesn't exist yet.
You could set up the event handler after creating the element, use event bubbling, or use use .live.
Upvotes: 0
Reputation: 1769
the problem is that you "hide" button does not exist when you try to define the onclick event on it. I would suggest that you add it, set display=none, and then show it
Upvotes: 0
Reputation: 207861
It has to do with the order of elements being added to the page. If you drop the hide code within the show code it works (although you should check your logic):
$('.show').on('click', function() {
console.log('show clicked');
$('.myCss').append('<input type="button" class="hide" value="Hide"/>');
$('.hide').on('click', function() {
console.log('hide clicked');
$('.myCss').append('<input type="button" class="show" value="Show"/>');
});
});
In your original code, the code to bind the click event to the hide button exists prior to the actual hide button, so it isn't actually bound to anything. By moving it within the other code block you delay the execution of that chunk. You could also use .on()
to bind the click event to an event higher up in the DOM but it's really basically the same final result.
From the docs:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Upvotes: 5