javascript 如何将参数传递给图像加载事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17578280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass parameters into image load event?
提问by omega
When I set the src of an image object, it will trigger an onload function. How can I add parameters to it?
当我设置图像对象的 src 时,它会触发一个 onload 函数。如何向其添加参数?
x = 1;
y = 2;
imageObj = new Image();
imageObj.src = ".....";
imageObj.onload = function() {
context.drawImage(imageObj, x, y);
};
x = 3;
y = 4;
In here, I want to use the x and y values that were set at the time I set the src of the image (i.e. 1 and 2). In the code above, by the time the onload function would finish, x and y could be 3 and 4.
在这里,我想使用在设置图像的 src 时设置的 x 和 y 值(即 1 和 2)。在上面的代码中,当 onload 函数完成时,x 和 y 可能是 3 和 4。
Is there a way I can pass values into the onload function, or will it automatically use 1, and 2?
有什么方法可以将值传递给 onload 函数,还是会自动使用 1 和 2?
Thanks
谢谢
回答by Dan H
All the other answers are some version of "make a closure". OK, that works. I think closures are cool, and languages that support them are cool...
所有其他答案都是“关闭”的某种版本。好的,那行得通。我认为闭包很酷,支持它们的语言很酷......
However: there is a much cleaner way to do this, IMO. Simply use the image object to store what you need, and access it in the load handler via "this
":
但是:IMO,有一种更清洁的方法可以做到这一点。只需使用图像对象来存储您需要的内容,并通过“ this
”在加载处理程序中访问它:
imageObj = new Image();
imageObj.x = 1;
imageObj.y = 2;
imageObj.onload = function() {
context.drawImage(this, this.x, this.y);
};
imageObj.src = ".....";
This is a very general technique, and I use it all the time in many objects in the DOM. (I especially use it when I have, say, four buttons and I want them to all share an "onclick" handler; I have the handler pull a bit of custom data out of the button to do THAT button's particular action.)
这是一种非常通用的技术,我一直在 DOM 中的许多对象中使用它。(例如,当我有四个按钮并且我希望它们都共享一个“onclick”处理程序时,我特别使用它;我让处理程序从按钮中提取一些自定义数据来执行该按钮的特定操作。)
One warning: you have to be careful not to use a property of the object that the object class itself has a special meaning or use. (For example: you can't use imageObj.src
for any old custom use; you have to leave it for the source URL.) But, in the general case, how are you to know how a given object uses all its properties? Strictly speaking, you can't. So to make this approach as safe as possible:
一个警告:您必须小心不要使用对象类本身具有特殊含义或用途的对象属性。(例如:您不能imageObj.src
用于任何旧的自定义用途;您必须将其留给源 URL。)但是,在一般情况下,您如何知道给定对象如何使用其所有属性?严格来说,你不能。因此,为了使这种方法尽可能安全:
- Wrap up all your custom data in a single object
- Assign that object to a property that is unusual/unlikely to be used by the object itself.
- 将所有自定义数据包装在一个对象中
- 将该对象分配给该对象本身不寻常/不太可能使用的属性。
In that regard, using "x" and "y" are a little risky as some Javascript implementation in some browser may use those properties when dealing with the Image object. But this is probably safe:
在这方面,使用 "x" 和 "y" 有点冒险,因为某些浏览器中的某些 Javascript 实现在处理 Image 对象时可能会使用这些属性。但这可能是安全的:
imageObj = new Image();
imageObj.myCustomData = {x: 1, y: 2};
imageObj.onload = function() {
context.drawImage(this, this.myCustomData.x, this.myCustomData.y);
};
imageObj.src = ".....";
Another advantage to this approach: it can save a lot of memory if you are creating a lot of a given object -- because you can now share a single instance of the onload handler. Consider this, using closures:
这种方法的另一个优点是:如果您要创建大量给定对象,它可以节省大量内存——因为您现在可以共享 onload 处理程序的单个实例。考虑一下,使用闭包:
// closure based solution -- creates 1000 anonymous functions for "onload"
for (var i=0; i<1000; i++) {
var imageObj = new Image();
var x = i*20;
var y = i*10;
imageObj.onload = function() {
context.drawImage(imageObj, x, y);
};
imageObj.src = ".....";
}
Compare to shared-onload function, with your custom data tucked away in the Image object:
与共享加载功能相比,您的自定义数据隐藏在 Image 对象中:
// custom data in the object -- creates A SINGLE "onload" function
function myImageOnload () {
context.drawImage(this, this.myCustomData.x, this.myCustomData.y);
}
for (var i=0; i<1000; i++) {
imageObj = new Image();
imageObj.myCustomData = {x: i*20, y: i*10};
imageObj.onload = myImageOnload;
imageObj.src = ".....";
}
Much memory saved and may run a skosh faster since you aren't creating all those anonymous functions. (In this example, the onload function is a one-liner.... but I've had 100-line onload functions, and a 1000 of them would surely be considered spending a lot of memory for no good reason.)
由于您没有创建所有这些匿名函数,因此节省了大量内存并且可以更快地运行 skosh。(在这个例子中,onload 函数是单行的……但我有 100 行的 onload 函数,其中 1000 个肯定会被认为是无缘无故地消耗了大量内存。)
UPDATE: See use of 'data-*' attributefor a standard (and "standards approved") way to do this, in lieu of my ad-hoc suggestion to use myCustomData
.
更新:请参阅使用“data-*”属性作为标准(和“标准批准”)方法来执行此操作,而不是我的临时建议使用myCustomData
.
回答by gdoron is supporting Monica
Make a private scope closure that will store x & y values:
创建一个私有范围闭包来存储 x 和 y 值:
imageObj.onload = (function(x,y){
return function() {
context.drawImage(imageObj, x, y);
};
})(x,y);
回答by epascarello
Make a small function that handles it. Local variables will hold the correct scope.
制作一个处理它的小函数。局部变量将拥有正确的范围。
function loadImage( src, x, y) {
var imageObj = new Image();
imageObj.src = src;
imageObj.onload = function() {
context.drawImage(imageObj, x, y);
};
}
var x = 1,
y = 2;
loadImage("foo.png", x, y);
x = 3;
y = 4;
回答by Claudio Redi
You could use an anonymous function
你可以使用匿名函数
x = 1;
y = 2;
(function(xValue, yValue){
imageObj = new Image();
imageObj.src = ".....";
imageObj.onload = function() {
context.drawImage(imageObj, xValue, yValue);
};
})(x,y);
x = 3;
y = 4;