5

我会尽量保持简短。我在两个事件监听器之间交替,一个调用“goMetric”,另一个调用“goImperial”。unitSwitch 是在两者之间切换的链路。有没有更有效的方法来删除一个事件监听器并用另一个替换它?非常感谢有关如何编写更好的代码的任何其他提示。

(注意:我现在试图避免使用 jQuery,以便更好地理解 JavaScript。我想知道幕后发生了什么。)

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);
}

看起来好像有很多代码来做这么简单的事情。

4

3 回答 3

4

IMO 更好的方法是使用单个侦听器并将两者合并

function toggleMetricImperial() {
    isMetric = !isMetric;
    unitSwitch.innerHTML = isMetric ? "Go Imperial" : "Go Metric";
    ... other code ...
}

但是要删除一个侦听器并设置另一个侦听器,是的,您需要删除一个侦听器并设置另一个侦听器:-)

如果这在您的代码中很常见,那么您可以在像这样的库中考虑这种需求

function switcher(first, second) {
   var which = second;
   return function() {
       which = (which == first ? second : first);
       return which.apply(null, arguments);
   }
}

因此,通过将侦听器设置为,switcher(goImperial, goMetric)您将获得所需的内容。当然,在这种情况下,设置按钮标题将是“...其他代码...”部分的一部分。

switcher是一个被调用的高阶函数,给定两个函数返回一个函数,当被调用时将调用一个或另一个交替它们。请注意,给定的 Javascript 规则this可能需要将处理程序包装在一个函数中,该函数调用传递正确this. 例如,在 Javascript 中调用obj.meth();var m=obj.meth; m();.

于 2013-11-08T07:09:00.623 回答
3

我会这样写:

var isMetric = 假;
unitSwitch.addEventListener('click', onClick);

函数 onClick()
{
    isMetric = !isMetric;
    unitSwitch.innerHTML = (isMetric ? "Go metric" : "Go Imperial");
}

对于状态相关的操作,不需要两个不同的事件处理程序。

于 2013-11-08T07:03:46.807 回答
2

尝试像这样简单的事情......这只需要一个监听器,分配给一个处理切换逻辑的静态函数。rcpaul曾提到过类似的东西,但是以简写形式。

var isMetric = false;
unitSwitch.addEventListener('click', toggleUnit);

function goMetric() {
    isMetric = true;
    unitSwitch.innerHTML = "Go imperial";
}

function goImperial() {
    isMetric = false;
    unitSwitch.innerHTML = "Go metric";      
}

function toggleUnit() {
    if (isMetric) {
        goImperial();
    } else {
        goMetric();
    }
}

// Init
goMetric();
于 2013-11-08T07:24:06.803 回答