如何正确添加addeventlistener?

时间:2011-05-12 13:57:08

标签: javascript addeventlistener

我尝试使用图像事件监听器添加到数组,捕获加载事件并且它可以工作。但有时我传递给递减函数的参数对于所有请求都是相同的

var imgNumb = vectors.length;
function decrement(i, type){
    imgNumb--;
    console.log('Processed '+ type+' nr: ' + i + '. Left: '+ imgNumb);
}
for(var i in vectors)
{
    if(jQuery('#canvas-'+i).length != 0){
    var tempCont = document.getElementById('canvas-'+i);
    tempImage[i] = new Image();
    alert(i);
    tempImage[i].addEventListener('load', function(){
        decrement(i, 'canvas');
    }, false);
    type[i] = 'canvas';
       tempImage[i].src = tempCont.toDataURL();
    }
}

例如我得到:

Processed canvas nr: 1. Left: 2
Processed canvas nr: 2. Left: 1
Processed canvas nr: 2. Left: 0

但警告(如果它不在处理程序内)总是返回正确的密钥号。

2 个答案:

答案 0 :(得分:2)

您正在循环中创建一个依赖于循环变量的函数。所有功能都引用相同的 i。您必须引入一个新范围(通过调用函数)来捕获变量的当前值:

(function(index) {
    tempImage[index].addEventListener('load', function(){
        decrement(index, 'canvas');
    }, false);
}(i));

这里我们使用立即自我调用函数


Don't use for...in to iterate over arrays。使用正常的for循环。

答案 1 :(得分:1)

@Felix的回答是正确的,但我想我可能会展示一种更具可读性的替代解决方案:

var imgNumb = vectors.length,
    tempImage = [];

function decrement(i, type) {
    imgNumb--;
    console.log('Processed ' + type + ' nr: ' + i + '. Left: ' + imgNumb);
}

$.each(vectors, function(i, element) {
    var $canvas = $('#canvas-' + i);
    if ($canvas.length) {
        tempImage[i] = $('<img/>', {
            src: $canvas.get().toDataURL(),
            load: function() {
                decrement(i, 'canvas');
            }
        });
        type[i] = 'canvas';
    }
});

问题中不清楚vectors是jQuery对象还是普通JS数组,所以我采取了安全假设并使用了$.each()。如果vectors 是jQuery对象,则可以改为使用.each()

其他修正:

  • Don't use for... in to iterate over arrays.
  • 检查jQuery('#canvas-' + i).length
  • 的真实性
  • 您正在使用jQuery - 为什么要使用document.getElementById()
  • 同样,你正在使用jQuery - 为什么要使用addEventListener()