I'll try to keep it brief. I'm alternating between two event listeners, one that calls "goMetric" and the other that calls "goImperial". The unitSwitch is the link that switches between the two. Is there a more efficient way to remove one event listener and replace it with another? Any other tips on how to write better code are greatly appreciated.
(note: am trying to avoid jQuery for now, in order to better understand JavaScript. I want to know what goes on under the hood.)
var isMetric = false;
unitSwitch.addEventListener('click', goMetric);
function goMetric() {
isMetric = true;
// removed other code
unitSwitch.innerHTML = "Go imperial";
unitSwitch.removeEventListener('click', goMetric);
unitSwitch.addEventListener('click', goImperial);
}
function goImperial() {
isMetric = false;
// removed other code
unitSwitch.innerHTML = "Go metric";
unitSwitch.removeEventListener('click', goImperial);
unitSwitch.addEventListener('click', goMetric);
}
Just seems like a lot of code to do something so simple.
IMO a better approach would be just using a single listener and merging the two
function toggleMetricImperial() {
isMetric = !isMetric;
unitSwitch.innerHTML = isMetric ? "Go Imperial" : "Go Metric";
... other code ...
}
but for removing one listener and setting another, yes, you need to remove one listener and setting another :-)
If this is very common in your code then you could factor out this need in a library like
function switcher(first, second) {
var which = second;
return function() {
which = (which == first ? second : first);
return which.apply(null, arguments);
}
}
thus by setting the listener to switcher(goImperial, goMetric)
instead you would get what you are looking for. Of course in this case setting the button title would be part of the "... other code ..." section.
switcher
is a called an high-order function, that given two functions returns a function that when called will call one or the other alternating them. Note that given Javascript rules for this
you may need to wrap the handler in a function that calls the handler body passing the correct this
. In Javascript for example calling obj.meth();
is not the same as var m=obj.meth; m();
.
I would write this like this:
var isMetric = false; unitSwitch.addEventListener('click', onClick); function onClick() { isMetric = !isMetric; unitSwitch.innerHTML = (isMetric ? "Go metric" : "Go imperial"); }
There is no need for two distinct event handlers for state dependent action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With