admin管理员组文章数量:1304182
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 plete answer I've found thus far, however, it suggests that closures are the solution for all time. Curses! .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 plete 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
Share Improve this question asked May 19, 2011 at 23:15 Trass VasstonTrass Vasston 6732 gold badges6 silver badges23 bronze badges 5- Closures don't break IE. – Ryan Olds Commented May 19, 2011 at 23:17
- 3 What makes you say closures break IE? They are a fundamental language feature. – rjmunro Commented May 19, 2011 at 23:18
- 2 @rjmunro I think he's referring to the IE6/7 memory leak when using closures and event binding callbacks. – Raynos Commented May 19, 2011 at 23:20
- @rjmunro @Raynos indeed, we are targeting ie7, though it says here that ie 7 usage is at like 7% – Trass Vasston Commented May 19, 2011 at 23:24
- 2 Targeting IE7? Don't stand too close, shit my splatter on you. – Ryan Olds Commented May 19, 2011 at 23:30
4 Answers
Reset to default 9Closures 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 bees 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.
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.
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);
}
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);
}
本文标签:
版权声明:本文标题:pass variables to an event javascript - no closures, no jq, avoid evals & such - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741781138a2397317.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论