Reputation: 4755
I was trying to execute some alerts with some onclick events and conditions with jquery statement. But it seems that event handlers don't work properly, probably due the fact that is missing something in my event handling logic. I have just 1 button, with id #bottone1
, and I have some menu buttons with id #b1
and #b2
.
The first event works fine, it adds correctly the class "cliccatoInvoca1_OnReady
". When i click on #bottone1
it starts the the first alert "cliccatoInvoca1_OnReady
". Also the onClick
event $("#b1")
works properly, it removes the class "cliccatoInvoca1_OnReady
" and replaces with the class "cliccatoInvoca1
".
When i click on #bottone1
it comes like first alert "cliccatoInvoca1_OnReady
", and then "cliccatoInvoca1". Then when i click on #b2
and afer that i click on #bottone1
it executes 3 alerts, "cliccatoInvoca1_OnReady
", "cliccatoInvoca1
" and finally "cliccatoInvoca3
".
So, the main problem is that it doesn't work if condition for execute only 1 alert at time. So when i click on #bottone1
it executes all the alerts in sequence.
$(document).ready(function () {
$("#select-1").multiselect();
invoca1();
$("#bottone1").addClass("cliccatoInvoca1_OnReady btn btn-default");
if ($("#bottone1").hasClass("cliccatoInvoca1_OnReady")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca1_OnReady");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
if ($("#bottone1").hasClass("cliccatoInvoca1")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca1");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
});
$("#b2").click(function () {
invoca3();
$("#bottone1").removeClass("cliccatoInvoca1").addClass("cliccatoInvoca3");
if ($("#bottone1").hasClass("cliccatoInvoca3")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca3");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
});
});
Upvotes: 0
Views: 780
Reputation: 93561
Change to use delegated event handlers, attached to a non-changing ancestor element, each with a matching selector:
e.g. like this:
$(document).on('click', "#bottone1.cliccatoInvoca1_OnReady", function() {
alert("cliccatoInvoca1_OnReady");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
The above is now all you need for one click handler, repeat the pattern for the other classes it can have. You never need the hasClass
checks.
Your other code just becomes simple like this:
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
});
click
) to bubble up to the ancestor element. document
is the default if nothing else is closer/convenient. Do not use 'body'
as it has a bug related to styling that can cause mouse events not to bubble to it.This pattern will simplify your code significantly.
The entire example will become something like this:
$(document).ready(function () {
$("#select-1").multiselect();
invoca1();
$("#bottone1").addClass("cliccatoInvoca1_OnReady btn btn-default");
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
});
$("#b2").click(function () {
invoca3();
$("#bottone1").removeClass("cliccatoInvoca1").addClass("cliccatoInvoca3");
});
$(document).on('click', "#bottone1.cliccatoInvoca1", function () {
alert("cliccatoInvoca1");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
$(document).on('click', "#bottone1.cliccatoInvoca3", function () {
alert("cliccatoInvoca3");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
});
Upvotes: 5