将变量传递给事件 javascript - 没有闭包,没有 jq,避免 evals &这样的

发布于 2024-11-08 02:29:21 字数 850 浏览 0 评论 0原文

好吧,每个人都已经解决了这个问题,但是我觉得还没有更了解该怎么做。

我想要一个循环来设置一堆点击处理程序,并为每个处理程序提供唯一的参数。我现在正在做这样的事情:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

三岁铭 2024-11-15 02:29:21

闭包不会破坏 IE。

(function(someThing) {
    myDiv.onclick=function(){
       // Access it as "someThing"
    }
})(thisThing);

jsFiddle

问题是分配给 onclick 属性的函数创建了一个闭包,可以在其中访问其父变量。

当您准备好单击某个元素时,其 thisThing 已递增到终止循环的最终值(在您的情况下迭代的最后一个属性),因为它访问外部变量,而不是复制。

通过使用新的自调用函数创建新的闭包并传递 thisThing,其值将成为变量 someThing 并仅存在于内部函数内部。

这是缓解这个已知问题的方法之一。

请注意,在 IE6 和 IE6 中7.存在内存泄漏。咨询 RobG Raynos 对此问题的解决方案的回答

Closures do not break IE.

(function(someThing) {
    myDiv.onclick=function(){
       // Access it as "someThing"
    }
})(thisThing);

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 variable someThing 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.

谁对谁错谁最难过 2024-11-15 02:29:21

问题是在循环中创建函数是。一点点重构就能让你的问题消失。

function createDiv(thing) {
    var div = ...
    div.onclick = ...
}

for (thisThing in things) {
    createDiv(thisThing);
}

但在旧版本的 IE 中这仍然会泄漏内存。

这是因为这段代码:

var div = ...;
div.onclick = function() { ...;

div 有一个对函数的引用,而函数有一个对 div 的引用。这是一个循环引用。要解决这个问题,您需要一个回调工厂。

function createDiv(thing) {
    var div = ...
    div.onclick = createCallback(thing);
}

function createCallback(thing) {
    return function() {
         ...
    };
}

这意味着您的 onclick 回调没有对您的 div 元素的引用。

The problem is creating functions in loops is BAD. A little bit of refactoring makes your problem disappear.

function createDiv(thing) {
    var div = ...
    div.onclick = ...
}

for (thisThing in things) {
    createDiv(thisThing);
}

But this still leaks memory in older versions of IE.

It's because of this code :

var div = ...;
div.onclick = function() { ...;

The div has a refence to the function and the function has a reference to the div. This is a circular reference. To remove this problem you need a callback factory.

function createDiv(thing) {
    var div = ...
    div.onclick = createCallback(thing);
}

function createCallback(thing) {
    return function() {
         ...
    };
}

This means your onclick callback has NO reference to your div element.

找回味觉 2024-11-15 02:29:21

我想要一个循环来设置
一堆点击处理程序并且每个都有
处理程序给出唯一的参数。我是
现在正在做这样的事情:

> 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!
>     } }

到处都说这个问题的解决方案是闭包

不,你根本不想要闭包。您正在尝试关闭。

除了闭包会破坏 ie(对吗?)

错误。

IE 和涉及 DOM 元素的循环引用存在问题,导致内存泄漏。这个问题已基本得到解决,但仍存在很多误解。例如:

function addListener(element) {
    var someVar = ...;
    element.onclick = function() {
        // this function has a closure to someVar
    };
}

当调用 addListener 时,导致涉及 someVar 闭包的循环引用。有一些非常简单的修复方法。您想要做的是关闭 someVar,而是使用该值。这可以通过多种方式完成,但最简单的是:


函数 addListener(元素) {
var someVar = ...;
element.onclick = (函数( differentVar ) {
警报(不同的变量);
})(一些VAr);
}

所以现在 someVar 的被传递给 differentVar,它是内部函数的局部变量。当然,内部函数可能仍然具有 someVar 的闭包,但是使用立即调用的匿名函数会破坏 differenceVarsomeVar 之间的闭包。

作为其中之一,无论如何关闭都没有问题。但是,如果您附加了多个侦听器,并且它们都引用了 someVar,那么它们都共享相同的值。在两者之间使用立即调用的匿名函数会破坏该链。

编辑

抱歉,最后一个例子不正确,我的错。

function addListener(element) {
    var someVar = ...;
    element.onclick = (function(differentVar) {
        return function() {
          alert(differentVar);
        };
    })(someVAr);
}

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

No, you don't want closures at all. You are trying to not have closures.

except closures break ie (right?)

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:

function addListener(element) {
    var someVar = ...;
    element.onclick = function() {
        // this function has a closure to someVar
    };
}

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 and someVar.

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.

function addListener(element) {
    var someVar = ...;
    element.onclick = (function(differentVar) {
        return function() {
          alert(differentVar);
        };
    })(someVAr);
}
独夜无伴 2024-11-15 02:29:21

闭包不会破坏 IE。

for (thisThing in things){
    if(!things.hasOwnProperty(thisThing)) continue;

    var myDiv = new document.createElement('img');
    myDiv.onclick = (function(thing){
        // Instance specific vars and other thigns
        return function() {
            // More stuff
        }
    })(thisThing);
}

Closures don't break IE.

for (thisThing in things){
    if(!things.hasOwnProperty(thisThing)) continue;

    var myDiv = new document.createElement('img');
    myDiv.onclick = (function(thing){
        // Instance specific vars and other thigns
        return function() {
            // More stuff
        }
    })(thisThing);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文