I am new to jQuery as well as Web development. :-)
I want to create a questions creation page. It has a Question Text Box and a Add Button. When users press the add button, there will be a new Question Text Box and a new Add Button appear in the next line. But the old Add Button will become a Delete Button and change its functionality.
开发者_StackOverflow社区Here is jQuery code:
$(function () {
$(".buttonMinus").hide();
$(".buttonPlus").click(function (event) {
$(this).remove(".buttonPlus");
$(".buttonMinus").show();
$("#p1").append("<p id='p2'>Question: <input type='text'><button type='button' class='buttonPlus'></button></p>"); **// Here !!!!**
alert("Welcome " + $(".ttt").val() + "!");
});
$(".buttonMinus").click(function (event) {
alert("You have pressed the DELETE button!");
});
});
And here is the html code:
<body>
<div class="demo">
<p id="p1">Your name: <input type="text" class="ttt"/>
<button class="buttonPlus" type="button"></button>
<button class="buttonMinus" type="button"></button></p>
<br />
</div>
</body>
I put all the Add Buttons and Minus Buttons into two different classes, ".buttonPlus" and ".buttonMinus". The .buttonPlus works well when the line is added by the main html. But it fails to work when it is added by the .append() function. It simply adds the .buttonPlus's CSS code to its button, but the $(".buttonPlus").click(function (event) {...} is NOT attached to the new buttonPlus.
Could you guys tell me why and how I can solve this problem?
Thanks, Ashley
Welcome to jQuery! This is a common issue. The problem is caused by the fact that the new .buttonPlus
element does not exist at the time when you first bind the click
event to .buttonPlus
. That first time you bind the click
event, it will only bind to elements that already exist on the page. This is the entire reason why you wrap all your code inside $(function())
-- it ensures that it does not run until all the DOM elements have been created.
There are a few different solutions. The simplest one is to use jQuery's .live()
method, as Ryan suggests. This will automatically bind the specified click
event to any new .buttonPlus
elements that get created.
However, while this is the simplest solution, it's also very computationally expensive. I won't get into the details here, but using .live()
is pretty much never the best option. There is a similar jQuery method called .delegate()
which can be used instead. However, while .delegate()
is less expensive than .live()
, it's still not the best solution in your case.
The best solution, as Diodeus alludes to, is to "re-bind these elements when they're added." You could do that in the following way:
function btnClickEvent(btn){
btn.remove(".buttonPlus");
$(".buttonMinus").show();
$("#p1").append("<p id='p2'>Question: <input type='text'><button type='button' class='buttonPlus'></button></p>");
alert("Welcome " + $(".ttt").val() + "!");
//Re-binding
var newBtn = $("#p1").find('.buttonPlus:last');
newBtn.click(function(){
btnClickEvent(newBtn);
});
}
$(function(){
$(".buttonMinus").hide();
$(".buttonPlus").click(function(){
btnClickEvent($(this));
});
$(".buttonMinus").click(function (event) {
alert("You have pressed the DELETE button!");
});
}
As you can see, all we're doing is putting the code that runs on the click
event into a separate function. That allows us to easily bind it to the new button. You would probably want to do a similar thing with your minus buttons as well.
When you create a click handler only the elements currently on the page get hooked up. Those added later do not.
You can either re-bind these elements when they're added, or use jQuery's .live()
feature that will do that for you automatically.
Here is a modified, but working version of what you've got going on in your code...
You'll likely want to use jQuery's live() function like this...
$(".buttonPlus").live("click",function (event) {
$(this).remove(".buttonPlus");
$(".buttonMinus").show();
$("#p1").append("<p id='p2'>Question: <input type='text'><button type='button' class='buttonPlus'></button></p>"); **// Here !!!!**
alert("Welcome " + $(".ttt").val() + "!");
});
$(".buttonMinus").live("click",function (event) {
alert("You have pressed the DELETE button!");
});
What this does is applies the same event handling to elements not yet in the DOM as they are added.
精彩评论