将变量传递给事件 javascript - 没有闭包,没有 jq,避免 evals &这样的
好吧,每个人都已经解决了这个问题,但是我觉得还没有更了解该怎么做。
我想要一个循环来设置一堆点击处理程序,并为每个处理程序提供唯一的参数。我现在正在做这样的事情:
for (thisThing in things){
myDiv=document.createElement('img');
myDiv.onclick=function(){
// do somehting!
// but don't do anything with "thisThing"
// because it's got the wrong value in it by the time you call it!
// but this function has to have the value of "thisThing" to work, dammit!
}
}
- 到处都说这个问题的解决方案是闭包 - 哇太棒了!除了闭包会破坏即(对吗?)
- 否则,我可以当场评估代码,在变量中进行烘焙,但这充其量看起来很丑陋,而且似乎可能会破坏一些东西
那么这会给我留下什么?倒闭好吗?评估好吗?我是唯一一个在网络上动态创建按钮的人吗?!?任何帮助将不胜感激。对于这个基本问题和事实上经常回答的问题感到抱歉。
此页面具有迄今为止我找到的最完整的答案,但是,它表明闭包始终是解决方案。诅咒! http://www.howtocreate.co.uk/referencedvariables.html
ok, this has been addressed by everybody, but yet I feel no closer to understanding what to do.
I want to have a loop that sets a bunch of click handlers and have each handler given unique parameters. I'm doing somehting like this now:
for (thisThing in things){
myDiv=document.createElement('img');
myDiv.onclick=function(){
// do somehting!
// but don't do anything with "thisThing"
// because it's got the wrong value in it by the time you call it!
// but this function has to have the value of "thisThing" to work, dammit!
}
}
- All over the place the solution for this is said to be closures - wow great! except closures break ie (right?)
- Elsewise, I can eval the code on the spot, baking in the varibles, but that seems ugly at best, and seems like it might break some thing
So what does this leave me? Are closures ok? is evaling ok? AM I THE ONLY PERSON DYNAMICALLY CREATING BUTTONS ON THE WEB?!? Any help will be much appreciated. sorry about the elementary &, in fact, frequently answered question.
this page has the most complete answer I've found thus far, however, it suggests that closures are the solution for all time. Curses! http://www.howtocreate.co.uk/referencedvariables.html
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
闭包不会破坏 IE。
jsFiddle。
问题是分配给 onclick 属性的函数创建了一个闭包,可以在其中访问其父变量。
当您准备好单击某个元素时,其
thisThing
已递增到终止循环的最终值(在您的情况下迭代的最后一个属性),因为它访问外部变量,而不是复制。通过使用新的自调用函数创建新的闭包并传递 thisThing,其值将成为变量 someThing 并仅存在于内部函数内部。
这是缓解这个已知问题的方法之一。
请注意,在 IE6 和 IE6 中7.存在内存泄漏。咨询 RobG 或 Raynos 对此问题的解决方案的回答。
Closures do not break IE.
jsFiddle.
The problem is the function assigned to the
onclick
property creates a closure where it has access to its parents variables.By the time you are ready to click an element, its
thisThing
has been incremented to the final value that terminates the loop (the last property iterated over in your case) because it accesses the outer variable, not a copy.By creating a new closure with a new self invoking function and passing
thisThing
, its value becomes the variablesomeThing
and lives inside of the inner function only.This is one of the ways of mitigating this known problem.
Note that in IE6 & 7 there is a memory leak. Consult RobG or Raynos's answer for a solution to this issue.
问题是在循环中创建函数是坏。一点点重构就能让你的问题消失。
但在旧版本的 IE 中这仍然会泄漏内存。
这是因为这段代码:
div
有一个对函数的引用,而函数有一个对div
的引用。这是一个循环引用。要解决这个问题,您需要一个回调工厂。这意味着您的
onclick
回调没有对您的div
元素的引用。The problem is creating functions in loops is BAD. A little bit of refactoring makes your problem disappear.
But this still leaks memory in older versions of IE.
It's because of this code :
The
div
has a refence to the function and the function has a reference to thediv
. This is a circular reference. To remove this problem you need a callback factory.This means your
onclick
callback has NO reference to yourdiv
element.不,你根本不想要闭包。您正在尝试不关闭。
错误。
IE 和涉及 DOM 元素的循环引用存在问题,导致内存泄漏。这个问题已基本得到解决,但仍存在很多误解。例如:
当调用 addListener 时,导致涉及 someVar 闭包的循环引用。有一些非常简单的修复方法。您想要做的是不关闭 someVar,而是使用该值。这可以通过多种方式完成,但最简单的是:
函数 addListener(元素) {
var someVar = ...;
element.onclick = (函数( differentVar ) {
警报(不同的变量);
})(一些VAr);
}
所以现在 someVar 的值被传递给 differentVar,它是内部函数的局部变量。当然,内部函数可能仍然具有 someVar 的闭包,但是使用立即调用的匿名函数会破坏
differenceVar
和someVar
之间的闭包。作为其中之一,无论如何关闭都没有问题。但是,如果您附加了多个侦听器,并且它们都引用了 someVar,那么它们都共享相同的值。在两者之间使用立即调用的匿名函数会破坏该链。
编辑
抱歉,最后一个例子不正确,我的错。
No, you don't want closures at all. You are trying to not have closures.
Wrong.
There was an issue with IE and circular references involving DOM elements causing memory leaks. That issue has largely been fixed, however it is much misunderstood. For example:
Causes a cicular reference involving the closure to someVar when addListener is called. There was some pretty simple fixes for that. What you want to do is not have a closure to someVar, but use the value. That can be done a number of ways, but the simplest is:
function addListener(element) {
var someVar = ...;
element.onclick = (function(differentVar) {
alert(differentVar);
})(someVAr);
}
So now the value of someVar is passed to differentVar, which is a local variable of the inner function. Of course the inner function may still have a closure to someVar, but the use of the use of an immediately called anonymous function breaks the closure between
differentVar
andsomeVar
.As a one-of, there is no issue with the closure anyway. But where you are attaching a number of listeners and they all have a reference to someVar, then they all share the same value. Using an immediately called anonymous function in between breaks that chain.
Edit
Sorry, that last example is incorrect, my bad.
闭包不会破坏 IE。
Closures don't break IE.