[英]ForEach function with event listener
I am trying to repeat less in my code. 我试图在我的代码中减少重复。 In some of my codes that have many elements, I feel like i'm doing too much.
在我的一些包含很多元素的代码中,我觉得自己做得太多。 It's time I learned how to reduce code and follow DRY techniques.
是时候该学习如何减少代码并遵循DRY技术了。
The code below is how I am currently attaching eventListeners to my elements. 下面的代码是我当前如何将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);
I have been trying to use the forEach loop. 我一直在尝试使用forEach循环。 But i am having issues with the function.
但是我在功能上有问题。 For starters, it seems the function is being triggered preemptively.
对于初学者来说,该功能似乎是抢先触发的。 And because I expect the my main load to reflect any changes, it creates and infinite loop and crashes.
而且因为我希望我的主要负载能够反映出任何变化,所以它会造成无限循环并崩溃。 I am using VS2015, and i try to write using plain JS without any libraries... please, no jquery.
我正在使用VS2015,我尝试使用不带任何库的纯JS编写...请不要使用jquery。
Here is my attempt at the forEach loop: see edits at the bottom. 这是我对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);
});
That function is in my "UI.myLoad" code block. 该函数在我的“ UI.myLoad”代码块中。 Here is UI.atFunc(key)...
这是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.
},
the expected behavior is that when any key is clicked, the value of 1 integer should be added to its perspective item in local storage, and UI.myLoad just loads the main themes, values, and timeouts on the app. 预期的行为是,当单击任何键时,应将1整数的值添加到本地存储中的透视图项中,并且UI.myLoad只会在应用程序上加载主要主题,值和超时。 But because my forLoop is in that code block, it is causing a crash.
但是因为我的forLoop在该代码块中,所以导致崩溃。 I moved it outside of the scope on UI.myLoad, but then it didn't work at all.
我将其移至UI.myLoad范围之外,但随后根本不起作用。 Is there something wrong with the code?
代码有问题吗? or am i going about this the wrong way and should attempt to just use a for loop instead?
还是我会以错误的方式进行操作,应该尝试仅使用for循环? I've seen examples of the forEach working properly but i can't do it right myself.
我已经看到了forEach正常运行的示例,但我自己做不到。
[edit: The code below is a solution that used the accepted answer, but found another problem. [编辑:以下代码是使用了已接受答案的解决方案,但发现了另一个问题。 The full solution is now identified.]
现在确定了完整的解决方案。]
(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();
}
}())
Your problem stems from atFunc
. 您的问题源于
atFunc
。 The reason it's "being triggered preemptively" is because you're immediately calling the function. 它“被抢先触发”的原因是因为您正在立即调用该函数。
ele.addEventListener("click", UI.atFunc(key), false);
What this does is runs the function UI.atFunc
then returns the value of undefined
. 这样做是运行函数
UI.atFunc
然后返回undefined
的值。 This basically translates your above line into: 这基本上可以将您的上述代码转换为:
UI.atFunc(key);
ele.addEventListener("click", undefined, false);
Instead, you want to return a function which captures the correct key. 相反,您想返回一个捕获正确键的函数。 Since functions are just like any other value in JS, you can return one like this:
由于函数与JS中的任何其他值一样,因此您可以返回以下内容:
atFunc: function(key) {
return function() {
var value = localStorage.getItem(key);
...
};
}
This way you return a new function value instead of a undefined
and that function is bound to the click event. 这样,您将返回一个新的函数值而不是
undefined
值,并且该函数绑定到click事件。
The issue is the way the function is added in addEventListener
. 问题是在
addEventListener
添加函数的方式。
In the first code, you correctly reference the function 在第一个代码中,您正确地引用了该函数
at1.addEventListener("click", UI.at1Func, false);
But in the second code, you've added parentheses, and parentheses calls the function right away and returns the result, which would be undefined
. 但是在第二个代码中,您添加了括号,并且括号立即调用了该函数并返回结果,该结果将是
undefined
。
There are many ways to solve this, but probably the easiest in your case would be to modify the atFunc
function with a closure and return a function 有很多方法可以解决此问题,但是在您的情况下,最简单的方法可能是使用闭包修改
atFunc
函数并返回一个函数
atFunc: function (key) {
return function() {
localStorage[key]++;
}
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.