Reputation: 1465
I know this is a known issue, and I've tried the stopPropagation
solution. It doesn't work. I'm baffled as to why this would happen anyway (I don't understand why it should). Anyway, here is the code.
I have a jQM button:
<a href="#" id="glossary_option1" class="ui-btn ui-btn-right ui-btn-icon-notext ui-nodisc-icon ui-alt-icon">No text</a>
And I use this code to toggle it on and off:
$("#glossary_option2").click(function(){
toggleGlos();
});
This calls this function, which will eventually also be called by glossary_option2, 3 and 4 (hence me having the function)
function toggleGlos() {
if (localStorage.glossaryopt === "off") {
$("#glossary_option1").removeClass("ui-icon-nobook").addClass("ui-icon-book");
$("#glossary_option2").removeClass("ui-icon-nobook").addClass("ui-icon-book");
$("#glossary_option3").removeClass("ui-icon-nobook").addClass("ui-icon-book");
$("#glossary_option4").removeClass("ui-icon-nobook").addClass("ui-icon-book");
console.log(localStorage.glossaryopt);
localStorage.glossaryopt = "on";
$(".glossaryLink").css({
"color": "white",
"background-color": "#CC8DCC",
"border": "1px solid white",
"padding": "0px 4px",
"font-size": "0.9em"
});
} else {
localStorage.glossaryopt = "off";
$("#glossary_option1").removeClass("ui-icon-book").addClass("ui-icon-nobook");
$("#glossary_option2").removeClass("ui-icon-book").addClass("ui-icon-nobook");
$("#glossary_option3").removeClass("ui-icon-book").addClass("ui-icon-nobook");
$("#glossary_option4").removeClass("ui-icon-book").addClass("ui-icon-nobook");
console.log(localStorage.glossaryopt);
$(".glossaryLink").css({
"color": "black",
"background-color": "white",
"border": "none",
"padding": "0",
"font-size": "1em"
});
}
}
Every time I click the button both parts of this function fire. glossaryopt is turned on then off, as shown by the console log.
I know this is a known issue but a. I can't fix it and b. I've done exactly this kind of thing many, many times. Why is it not working now?
Upvotes: 1
Views: 521
Reputation: 57309
jQuery Mobile
works in a different way then classic web applications. Depending on how you managed to bind your events each time you visit some page it will bind events over and over. This is not an error, it is simply how jQuery Mobile
handles its pages. For example, take a look at this code snipet:
$(document).on('pagebeforeshow','#index' ,function(e,data){
$(document).on('click', '#test-button',function(e) {
alert('Button click');
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/CCfL4/
Each time you visit page #index click event will is going to be bound to button #test-button. Test it by moving from page 1 to page 2 and back several times. There are few ways to prevent this problem:
Best solution would be to use pageinit
to bind events. If you take a look at an official documentation you will find out that pageinit
will trigger ONLY once, just like document ready, so there's no way events will be bound again. This is best solution because you don't have processing overhead like when removing events with off method.
Working jsFiddle example: http://jsfiddle.net/Gajotres/AAFH8/
This working solution is made on a basis of a previous problematic example.
Remove event before you bind it:
$(document).on('pagebeforeshow', '#index', function(){
$(document).off('click', '#test-button').on('click', '#test-button',function(e) {
alert('Button click');
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/K8YmG/
Use a jQuery Filter selector, like this:
$('#carousel div:Event(!click)').each(function(){
//If click is not bind to #carousel div do something
});
Because event filter is not a part of official jQuery framework it can be found here: http://www.codenothing.com/archives/2009/event-filter/
In a nutshell, if speed is your main concern then Solution 2 is much better then Solution 1.
A new one, probably an easiest of them all.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#test-button',function(e) {
if(e.handled !== true) // This will prevent event triggering more then once
{
alert('Clicked');
e.handled = true;
}
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/Yerv9/
Your best bet is:
$(document).off('click',"#glossary_option2").on('click',"#glossary_option2", function(){
toggleGlos();
});
Upvotes: 3