1

可能重复:
循环内的 Javascript 闭包 - 简单的实际示例

我在 phonegap 应用程序中遇到了关闭问题。我有一个 JSON 对象,其中包含有关如何创建表单的说明。大致是这样的代码:

for (var i in this.form.elements) {
    var element = this.form.elements[i];
    switch (element.type) {
        // other cases
        case 5:
            var addThumb, photoInput;
            addThumb = function (domId) {
                return function (imgData) {
                    console.log('id: ' + domId);
                    $(domId).attr({src: 'data:image/jpeg;base64,' + imgData});
                }
            }('#thumb-'+element.id);
            photoInput = $('<input>')
                .attr({type: 'button', value: element.name, name: element.type, id: element.id, 'class': 'photobutton'})
                .click(function (filename, cb) {
                    return function() {
                        console.log('taking photo and saving to ' + filename)
                        takePhoto(filename,addThumb)
                    }
                }('photo-'+element.id, addThumb)
            );
            photoThumb = $('<img>').attr({id: 'thumb-'+element.id, 'class': 'thumbnail', src: 'img/target.png'});
            $('#content').append(photoInput, photoThumb);
            break;
    }
}

单击照片按钮会打开相机以拍摄照片,并将照片保存到磁盘。保存后,使用 base64 照片数据调用 addThumb 以替换缩略图。我的测试表单的每个输出是:

taking photo and saving to file photo-686
id: '#thumb-690

拍照的闭包有效,但是当 addThumb 作为回调调用时,会domId显示通过 for 循环的最后一个 element.id。给定两个缩略图,无论按下哪个按钮,都会替换第二个缩略图。它发生在 iPhone 和 Android 上,所以我编写它的方式一定有问题。我做错什么了?

4

2 回答 2

2
takePhoto(filename, addThumb)

您需要cb从此处的闭包内部传递变量,而addThumb不是未“受保护”的变量。似乎您在“保护”它时忘记更改变量名。

于 2013-01-04T21:03:54.120 回答
1

问题是addThumb变量本身不受闭包的保护。它在创建时包含 d 的值,element.i但在下一次循环出现时被替换。所以你总是调用最后创建的addThumb函数。

您可以构建一个闭包来封闭,而不是尝试单独保护每个变量element

for (var i in this.form.elements) {
    var element = this.form.elements[i];
    (function(element){
       switch (element.type) {
       ...
    })(element);
}
于 2013-01-04T20:56:54.320 回答