I am writing a code that performs a function on click on a set of elements. It has a revalidate function. This revalidate function is fired on window resize. It checks if certain conditions are not fulfilled after resize then nothing should be done on click on body. This is an oversimplified version. Code:
var myFunction = function() {
// do something
}
var myCallback = myFunction;
$(".myClass").on("click", myCallback);
$(window).resize(function(){
if(//certain conditions are met) {
myCallback = undefined;
}
else {
myCallback = myFunction
}
});
I know I can use jquery off
to detach the handler. But the actual code is more complex. It is a plugin like code where if I click event is bound in certain conditions inside the plugin definition. If I use off
then to use On
again appropriately I might have to run the whole plugin code once again; that beats the purpose of revalidate
function. So,
Is it ok to execute undefined callback in event listeners?
PS: I have been also reading about jQuery.noop
. Seems like it's the exact situation to use that.
Your code doesn't call an undefined function, because the variable myCallback
is only evaluated when you bind the event handler, not every time the event occurs. To have the question you ask, it would have to be the following code:
$(".myClass").on("click", function(e) {
myCallback.call(this, e);
});
When myCallback
is set to undefined this will get an error, complaining that undefined
is has no property call
. What you should write is:
$(".myClass").on("click", function(e) {
if (myCallback) {
myCallback.call(this, e);
}
});
When you do this,
$(".myClass").on("click", myCallback);
A reference to myCallback
function is sent. When reassigning it, the callback (reference) sent to the on
function will not be changed.
What you probably wanted to do is something like this
$(".myClass").on("click", function(){ myCallback(); });
Now when myCallback
is undefined
, you'll get an error saying it's not a function. You could assign it an empty function instead of undefined
:
myCallback = function(){};
Alternately, you could check for the condition within the click
handler:
var condition = true;
var myFunction = function() {
if( !condition )
return;
// do something
}
$(".myClass").on("click", myFunction);
$(window).resize(function(){
if(//certain conditions are met) {
condition = false;
}
else {
condition = true;
}
});
The way which you tried didn't work as you didn't pass your callback physically, just a pointer to it. So doing
myCallback = undefined;
Doesn't clear your callback, it just changes pointer to undefined variable. jQuery saves information about your callback before you change the pointer. That's why it didn't work.
Consider refactoring to:
let guardian = true;
let clickHandler = function () {
if (guardian) {
/* your code */
}
};
$(".class").on("click", clickHandler);
$(window).resize( function () {
if (/* certain conditions are met */) {
guardian = false;
} else {
guardian = true;
}
});
In that case, we change guardian variable during resizing and check against it in our click handler. You don't have to on/off your callback handlers in such a case.
It's certainly not pretty code, and steps should be taken to make it obvious to other developers (or future-you) that this callback may not be a callback later on, but jQuery's .on method will not try and run anything that equates (think ==
) to false.
Therefore, setting your callback to undefined will not error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.