如何将参数传递到图像加载事件?

时间:2013-07-10 18:31:36

标签: javascript

当我设置图像对象的src时,它将触发onload函数。如何为其添加参数?

x = 1;
y = 2;
imageObj = new Image();
imageObj.src = ".....";
imageObj.onload = function() {
    context.drawImage(imageObj, x, y);
};
x = 3;
y = 4;

在这里,我想使用在设置图像的src(即1和2)时设置的x和y值。在上面的代码中,当onload函数完成时,x和y可以是3和4。

有没有办法可以将值传递给onload函数,还是会自动使用1和2?

由于

4 个答案:

答案 0 :(得分:32)

所有其他答案都是“make a closure”的某个版本。好的,那很有效。我认为闭包很酷,支持它们的语言很酷......

但是:有一种更清洁的方法可以做到这一点,IMO。只需使用图像对象存储您需要的内容,并通过“this”在加载处理程序中访问它:

imageObj = new Image();
imageObj.x = 1;
imageObj.y = 2;
imageObj.onload = function() {
    context.drawImage(this, this.x, this.y);
};
imageObj.src = ".....";

这是一种非常通用的技术,我一直在DOM中的许多对象中使用它。 (我特别使用它,当我有四个按钮时,我希望它们共享一个“onclick”处理程序;我让处理程序从按钮中拉出一些自定义数据来执行该按钮的特定操作。)

一个警告:您必须小心不要使用对象属性具有特殊含义或使用的对象属性。 (例如:您不能将imageObj.src用于任何旧的自定义用途;您必须将其保留为源URL。)但是,在一般情况下,您如何知道给定对象如何使用它属性?严格来说,你不能。所以要使这种方法尽可能安全:

  • 将所有自定义数据汇总到一个对象中
  • 将该对象分配给对象本身不常/不太可能使用的属性。

在这方面,使用“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 = ".....";

这种方法的另一个优点是:如果要创建大量给定对象,它可以节省大量内存 - 因为您现在可以共享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 = ".....";
}

与shared-onload函数比较,将自定义数据隐藏在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 = ".....";
}

由于您没有创建所有这些匿名函数,因此可以节省大量内存并且可以更快地运行。 (在这个例子中,onload函数是单行的....但是我有100行的onload函数,并且肯定会考虑其中1000个没有充分理由花费大量内存。)

答案 1 :(得分:11)

创建一个私有范围闭包,用于存储x&amp; y值:

imageObj.onload = (function(x,y){
        return function() {
            context.drawImage(imageObj, x, y);
    };
})(x,y);

答案 2 :(得分:9)

创建一个处理它的小函数。局部变量将保持正确的范围。

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;

答案 3 :(得分:5)

您可以使用匿名函数

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;