Всех остальных ответы некоторые версии «сделать закрытие ". Хорошо, это работает. Я думаю, что закрытие круто, а языки, которые их поддерживают, - это круто ...
Однако: существует намного более чистый способ сделать это, ИМО. Просто используйте объект изображения, чтобы сохранить то, что вам нужно, и получить доступ к нему в обработчик загрузки через «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 = ".....";
}
Сравнить с разделяемой 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 = ".....";
}
Много памяти сохранены и могут запустить skosh быстрее, так как вы Арен создавая все эти анонимные функции. (В этом примере функция onload является однострочным. Но у меня было 100-строчные функции onload, и 1000 из них наверняка считались бы тратить много памяти без уважительной причины.)
другой способ: imageObj.coords = {x: x, y: y}; ... drawImage (imageObj, imageObj.coords.x, imageObj.coords.y); – dandavis
COMP SCI TECHIE STUFF: Проблема выше в том, что функция onload ссылается на GLOBAL-переменные x и y ... и будет использовать значение then-current при выполнении. Чтобы правильно использовать закрытие - и иметь значения переменных «сохранены» от времени создания (закрытия) и использоваться при их исполнении - вам нужно использовать декларацию 'var', чтобы предоставить им область INSIDE для закрытия. (Это неявно происходит, если переменные являются формальными параметрами для функции, поэтому ответы на замыкание здесь «работают».) –