Reputation: 135
ran into a problem this morning. I wrote the following lines:
var Markup = '<div id="overlay"><h1>Test</h1><a id="close">Close</a></div>';
$(document).ready(function() {
$("#link").click(function() {
$("body").append(Markup);
$("#overlay").delay(500).animate({"opacity":"0.97"},2000);
});
$("#close").click(function() {
$("#overlay").delay(500).animate({"opacity":"0"},2000);
$("body").remove(Markup);
});
});
When I click on #link the overlay appears perfectly but the #close link doesn't work. Just nothing happens. The markup is also still there after clicking #close.
Any suggestions?
Upvotes: 0
Views: 1298
Reputation: 150010
A statement like this:
$("#close").click(function() { ... });
...has two parts. The first part:
$("#close")
creates a jQuery object containing all elements that exist in the DOM which match the supplied selector at that moment. (Though for an id selector there will be only one since id should be unique.)
The second part:
.click(function() { ... });
applies the .click()
method to whatever elements were in the jQuery object it was called on.
In your case you are running that line in your document ready handler before the "close" element exists, so effectively you are calling .click()
on an empty jQuery object and no handlers are bound. The two ways to fix this are to run the .click()
after adding the element, or move to a delegated event model where the click handler is bound to a parent element (in your case that would be the body):
$("body").on("click", "#close", function() {
// etc
With this delegated handler, when a click event occurs on the body jQuery checks if the target element matches the selector in the second parameter and if so it calls your function.
For the same effect with jQuery before version 1.7 use .delegate()
; for really old jQuery use .live()
.
Upvotes: 1
Reputation: 33865
The .click()
only work on elements that are in the DOM when the method is called, which in your case is when the DOM is ready. You need to use .on()
instead and delegate the click-event to a parent element (prior to version 1.7, you used .delegate()
instead of .on()
).
$("body").on("click", "#close", function() {
$("#overlay").delay(500).animate({"opacity":"0"}, 2000, function () {
$(this).remove();
});
// Prevent the default click-behavior
return false;
});
Notice
You should remove the content in the callback that is executed when the animation is completed. Otherwise there is a chance that the elements get removed before the animation is completed.
Upvotes: 3
Reputation: 7954
You need to delegate the event to it
$("body").delegate("#close","click",function() {
$("#overlay").delay(500).animate({"opacity":"0"},2000);
$("body").remove(Markup);
});
Upvotes: 0
Reputation: 318182
You are appending the element, and need to delegate the event:
$(document).ready(function() {
$("#link").on('click', function() {
Markup.appendTo($("body")).delay(500).animate({"opacity":"0.97"},2000);
});
$(document).on("click", "#close", function() {
$("#overlay").delay(500).animate({"opacity":"0"},2000, function() {
$(this).remove();
});
});
});
Upvotes: 0
Reputation: 988
This is because when the page is loaded the link with id of close does not exist yet, so the event is not bound to it. try .live()
Upvotes: 0