Reputation: 1387
With my add a box button (#purchase), I add boxes/items to the shopping carts. (this costs 25 of the credits)
When you click the orange div inside, the credits also decrease with an amount of 15 credits, and fades out the top div (so you can see which element has already cost 15 credits. Fading out happens only once, which is good, but while it's fading out, the user can still click the div, which causes the credits to decrease more than they should.
I tried some things with .one() but then it only works on one of the appended elements. Can anyone advise me how I can accomplish this? And why.
Code Html
<button id="purchase">Add a box </button>
<input id="money">
<div class="container"></div>
JS
var counter = 0;
$("#money").val(250);
$('#purchase').click(function() {
if ($("#money").val() < 25) {return;}
var box = $('<div class="box"' + (counter) + '><div class="yellow"' + (counter) + '><div class="buy"' + (counter) + '></div></div></div>').appendTo('.container');
$("#money").val(Number($("#money").val()) - 25).triggerHandler('change');
});
$('#money').change(function() {
$('#purchase').prop("disabled", $(this).val() < 25);
});
$('.container').on('click', '.buy', function() {
if ($("#money").val() < 15) {return;}
$(this).fadeOut(4000, callbackFunction);
$("#money").val(Number($("#money").val()) - 15).triggerHandler('change');
});
function callbackFunction() {
alert('done');
}
Upvotes: 2
Views: 2501
Reputation: 8059
bind the event when you create element:
var counter = 0;
$("#money").val(250);
$('#purchase').click(function() {
if ($("#money").val() < 25) {return;} // or alert('not enough money');
$('<div class="box">').data('counter',counter)
.append($('<div class="yellow">').data('counter',counter)
.append($('<div class="buy">').data('counter',counter).one('click',buy_click)
)).appendTo('.container');
$("#money").val(Number($("#money").val()) - 25).triggerHandler('change');
});
$('#money').change(function() {
$('#purchase').prop("disabled", $(this).val() < 25);
});
var callbackFunction=function() {};
var buy_click=function() {
if ($("#money").val() < 15) {return;}
$(this).fadeOut(4000, callbackFunction);
$("#money").val(Number($("#money").val()) - 15).triggerHandler('change');
};
use data() to keep data, not just numbers as you did
Upvotes: 1
Reputation: 1471
check the code and implement it for the elements you want the click to be implemented only once
$("purchase").one("click", function() {
if ($("#money").val() < 25) {return;}
var box = $('<div class="box"' + (counter) + '><div class="yellow"' + (counter) + '><div class="buy"' + (counter) + '></div></div></div>').appendTo('.container');
$("#money").val(Number($("#money").val()) - 25).triggerHandler('change');
});
Upvotes: 2
Reputation: 337570
You can use one()
to attach an event handler which should be run only once per element. Try this:
$('.container').one('click', '.buy', function() {
if ($("#money").val() < 15) {return;}
$(this).fadeOut(4000, callbackFunction);
$("#money").val(Number($("#money").val()) - 15).triggerHandler('change');
});
API reference: one()
Update
You can also achieve this manually using unbind()
:
$('.container').on('click', '.buy', function() {
$(this).unbind('click');
if ($("#money").val() < 15) {return;}
$(this).fadeOut(4000, callbackFunction);
$("#money").val(Number($("#money").val()) - 15).triggerHandler('change');
});
Upvotes: 4