Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More efficient way to alternate between two event listeners?

Tags:

javascript

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.

like image 280
kfrncs Avatar asked Nov 08 '13 06:11

kfrncs


2 Answers

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();.

like image 137
6502 Avatar answered Oct 12 '22 03:10

6502


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.

like image 36
Ronald Paul Avatar answered Oct 12 '22 04:10

Ronald Paul