我想在我的代码中重复一点。在我的一些代码中,有很多元素,我觉得我做得太多了。是时候我学会了如何减少代码并遵循DRY技术。
下面的代码是我当前如何将eventListeners附加到我的元素。
var at1, at2 ,at3 ,at4 ,at5 ,at6 , at7, at8,
at1 = UI.byId("at1");
at1.addEventListener("click", UI.at1Func, false);
at2 = UI.byId("at2");
at2.addEventListener("click", UI.at2Func, false);
at3 = UI.byId("at3");
at3.addEventListener("click", UI.at3Func, false);
at4 = UI.byId("at4");
at4.addEventListener("click", UI.at4Func, false);
at5 = UI.byId("at5");
at5.addEventListener("click", UI.at5Func, false);
at6 = UI.byId("at6");
at6.addEventListener("click", UI.at6Func, false);
at7 = UI.byId("at7");
at7.addEventListener("click", UI.at7Func, false);
at8 = UI.byId("at8");
at8.addEventListener("click", UI.at8Func, false);
我一直在尝试使用forEach循环。但我有这个功能的问题。对于初学者来说,似乎该功能正在被抢占式触发。而且因为我希望我的主要负载反映任何变化,它会产生无限循环和崩溃。我正在使用VS2015,我尝试使用没有任何库的普通JS编写...请,没有jquery。
以下是我对forEach循环的尝试:请参见底部的编辑。
var ats = ['at1', 'at2', 'at3', 'at4', 'at5', 'at6', 'at7', 'at8'];
ats.forEach(function (key) {
var ele = UI.byId(key);
ele.addEventListener("click", UI.atFunc(key), false);
});
该功能在我的“UI.myLoad”代码块中。这是UI.atFunc(key)...
atFunc: function (key) {
var value = localStorage.getItem(key);
localStorage.setItem(key, value++);
console.log(key);
//UI.myLoad(); //commented out to prevent crashing for now.
},
预期的行为是,当单击任何键时,应将1整数的值添加到本地存储中的透视项,并且UI.myLoad只会加载应用程序上的主要主题,值和超时。但是因为我的forLoop在那个代码块中,它导致崩溃。我把它移到UI.myLoad上的范围之外,但它根本不起作用。代码有问题吗?或者我是以错误的方式解决这个问题而应该尝试仅使用for循环?我已经看到forEach正常工作的例子但我不能自己做正确的事。
[编辑:下面的代码是使用已接受答案的解决方案,但发现了另一个问题。现在已确定完整的解决方案。]
(function () {
var UI;
UI = {
byId: function (id) {
return document.getElementById(id);
},
loadBtns: function () {
var ats = ['at1', 'at2', 'at3', 'at4', 'at5', 'at6', 'at7', 'at8'];
ats.forEach(function (key) {
var ele = UI.byId(key);
ele.addEventListener("click", UI.atFunc(key), false);
});
},
myLoad: function () {
//load and refresh elements
/*
var at1 = localStorage.getItem("at1");
if (!at1) {
spn1.innerText = 0;
}
if (at1) {
spn1.innerText = at1;
}
....
*/
},
atFunc: function (key) {
return function() {
var value = localStorage.getItem(key);
localStorage.setItem(key, +value + +1);
UI.myLoad();
};
}
}
window.onload = function () {
UI.myLoad();
UI.loadBtns();
}
}())
答案 0 :(得分:1)
您的问题源于atFunc
。它被抢先触发的原因是"是因为你立即调用了这个函数。
ele.addEventListener("click", UI.atFunc(key), false);
这样做是运行函数UI.atFunc
然后返回undefined
的值。这基本上将您的上述行转换为:
UI.atFunc(key);
ele.addEventListener("click", undefined, false);
相反,您希望返回一个捕获正确密钥的函数。由于函数与JS中的任何其他值一样,您可以返回如下:
atFunc: function(key) {
return function() {
var value = localStorage.getItem(key);
...
};
}
这样您就可以返回一个新的函数值而不是undefined
,并且该函数绑定到click事件。
答案 1 :(得分:0)
问题在于addEventListener
中添加功能的方式。
在第一个代码中,您正确引用了函数
at1.addEventListener("click", UI.at1Func, false);
但在第二个代码中,您添加了括号,并且括号立即调用该函数并返回结果,即undefined
。
有很多方法可以解决这个问题,但在您的情况下最简单的方法可能是使用闭包修改atFunc
函数并返回函数
atFunc: function (key) {
return function() {
localStorage[key]++;
}
},