Reputation: 35
This is my first question on stackoverflow so hopefully I'm doing it right.
I ran into an issue where a variable was passing a seemingly strange value through a click event. I figured out a different way to do it, but I'm curious as to why my original method wasn't working. I have a feeling it is a weird scoping rule of JS, so if someone could clarify, that would be great. The code was supposed to switch back and forth between two tabs on a click event. I'm sorry if this has already been answered, but in looking at others' questions I couldn't really tell if it was the same issue that I was having.
This was my original code, where at program start tab1
had the class active-tab
:
$("#tab1").on('click', {activeTab: $("#tab1").hasClass("active-tab"),
tab1Clicked: true}, changeTab);
$("#tab2").on('click', {activeTab: $("#tab1").hasClass("active-tab"),
tab1Clicked: false}, changeTab);
and elsewhere
function changeTab(event) {
var tab1Active = event.data.activeTab;
var tab1WasClicked = event.data.tab1Clicked;
if(tab1Active) {
if(tab1WasClicked)
alert("tab1 active & clicked, no change");
else {
alert("tab1 active, tab2 clicked, change");
$("#tab1").removeClass("active-tab");
$("#tab2").addClass("active-tab");
}
}
else {//tab2 is active
if(tab1WasClicked) {
alert("tab2 active, tab1 clicked, change");
$("#tab2").removeClass("active-tab");
$("#tab1").addClass("active-tab");
}
else
alert("tab2 active & clicked, no change");
}
}
The problem was that, although the .hasClass
calls returned the correct result, the value of event.data.activeTab
always turned out to be true
, so once tab2
got clicked it never made tab1
active again because it always thought it already was, even though the class did in fact get removed. I solved this by passing only tab1Clicked
through event.data
and just checking $("#tab1").hasClass("active-tab")
directly in the function changeTab
, which is probably what I should have been doing from the beginning, but still, can someone explain to me why this other method didn't work equally well?
Upvotes: 2
Views: 152
Reputation: 413757
The "data" expressions are evaluated once, at the point where the event handler is set up. They aren't (and can't be) re-evaluated for each actual event. This code:
$("#tab1").on('click', {activeTab: $("#tab1").hasClass("active-tab"),
tab1Clicked: true}, changeTab);
is evaluated by computing the value expressions for that data object. What's passed to the jQuery .on()
function therefore is an object with two properties, each with a fixed value (booleans, in this case). They'll never change after that, because there's no trace of the expressions that initialized the property values.
In this case, the simplest solution is to simply move the tests into the function, as you say.
Upvotes: 2