Guffa 的解决方案可能就足够了,但在循环中创建闭包通常不是一个好主意。我有一种不同的方法,它不需要您对代码进行太多重构,并提供了一个可重用的组件,尽管代码更多:
// CALLBACK MANAGER MODULE BEGIN
// Create a manager for creating callbacks.
var callbackManager = (function () {
var win = window,
random = Math.random,
// Create a hash for us to save all callbacks on.
callbacks = {},
// Generates the next unique ID for a callback.
nextId = (function () {
var next = 1;
return function () {
var n = next;
next += 1;
return n;
};
}()),
// Generates the next valid callback name.
nextCallbackName = function (prefix) {
prefix = prefix || "___callback";
return prefix + nextId();
};
// Save our hash of callbacks on the window object
// so we can get access to the callbacks globally.
win.callbacks = callbacks;
return {
// Creates a callback that will call the specified
// method on the 'thisObj'. Can specify optional arguments
// to have passed to the method call:
//
// callbackManager.makeMethodCallCallback(myObj, "welcome", "Alex");
//
// The callback will be returned and saved so it can
// be accessed globally.
//
// Each callback will be a function with the following methods:
// getPath - Get the exported (i.e. global) path of the callback.
// dispose - Disposes the callback by nulling out all references
// and removing it from global access.
//
// makeCallback(thisObj, methodName, ...)
makeMethodCallCallback: function (thisObj, methodName) {
var name = nextCallbackName(),
args = Array.prototype.slice.call(arguments, 2),
callback = function () {
if (thisObj &&
typeof thisObj[methodName] === "function") {
return thisObj[methodName].apply(thisObj, args);
}
};
callback.getPath = function () {
return "window.callbacks." + name;
};
callback.dispose = function () {
thisObj = null;
callback = null;
args = [];
delete callbacks[name];
};
return callback;
};
};
}());
// CALLBACK MANAGER MODULE END
function imgHandler(divname) {
this.imgDiv = divname;
this.img = Array("bigoldlizard.png","scarytiger.gif");
// Define an array of callbacks.
var callbacks = [];
this.update = function() {
var htmlstr = "",
// Declare a local variable for a callback.
callback;
for(i=0; i<this.img.length; i++) {
// Create a new callback and save it so we can dispose it when
// this image is removed. We also pass the index of the image.
callback = callbackManager.makeMethodCallCallback(this, "remove", i);
callbacks.push(callback);
// All callbacks have a getPath() method that will return
// the callback's exported (i.e. global) path, such as "window.callbacks.__callback92".
htmlstr += '<img src="' + this.img[i] + '" onclick="' + callback.getPath() + '(); return false;/></span>';
}
$("#" + this.imgDiv).html(htmlstr);
}
//remove an image from the array
this.remove = function(index) {
if (index >= 0 && index < this.img.length) {
this.img.splice(index, 1);
this.update();
// Dispose the callback associated to this image
// then tombstone it so that the order other callbacks
// will be maintained.
if (callbacks[index]) {
callbacks[index].dispose();
// Tombstone the callback.
callbacks[index] = undefined;
}
return true;
}
else
return false;
}
}
Guffa 的技术和这个应该可以解决问题。
编辑:我没有意识到你正在使用 jQuery。如果可以的话,我建议使用 jQuery 的click()
事件助手而不是属性。onclick
也许尝试结合我callbackManager
和 Guffa 的方法可以提供两全其美的方法;创建<img>
元素并使用 jQuery 的click()
帮助器并使用可重用的回调管理器模块。