JavaScript/jQuery图片加载事件监听在IE中的问题

23

我正在寻找一种实现方法,可以在尽可能多的浏览器上使用:

var image = new Image();
image.addEventListener("load", function() {
    alert("loaded");
}, false);
image.src = "image_url.jpg";

这在IE中不起作用,因此我查了一下谷歌,发现低于9版本的IE不支持.addEventListener()。 我知道有一个名为.bind()的jQuery等效函数,但它不适用于Image()。 我需要做什么才能使其在IE中也能正常工作?

5个回答

30

IE支持使用attachEvent。

image.attachEvent("onload", function() {
    // ...
});

使用 jQuery,你只需要写下以下代码:

$(image).load(function() {
    // ...
});

如果涉及到事件处理,如果可能使用jQuery,我建议使用它,因为它会处理浏览器兼容性问题。这样你的代码将可以在所有主流浏览器上运行,你不必担心这个问题。

还要注意,在IE中为了触发load事件,你需要确保图像不是从缓存加载的,否则IE将不会触发load事件。

为了实现这一点,你可以在图像URL的末尾添加一个虚拟变量,像这样:

image.setAttribute( 'src', image.getAttribute('src') + '?v=' + Math.random() );

使用jQuery的load方法时一些已知问题包括:

当与图片一起使用时,load事件存在注意事项

开发人员尝试使用.load()快捷方式解决的常见问题是在图像(或图像集)完全加载后执行函数。这方面有几个已知注意事项,应该注意。它们是:

  • 它在跨浏览器时不一致且不可靠
  • 如果图像src设置为与之前相同的src,则在WebKit中不会正确触发
  • 它不能正确冒泡到DOM树
  • 对于已经存在于浏览器缓存中的图像,可能停止触发

有关更多信息,请参见jQuery文档


8

您需要使用.attachEvent()而不是.addEventListener()查看浏览器兼容性

if (image.addEventListener) {
  image.addEventListener('load', function() {
       /* do stuff */ 
  });
} else {
  // it's IE!
  image.attachEvent('onload', function() {
    /* do stuff */
  });
}

2

new Image 基本上返回一个 <img> 标签,所以你可以像 jQuery 一样编码:http://jsfiddle.net/pimvdb/LAuUR/1/

$("<img>", { src: '...' })
    .bind('load', function() {
        alert('yay');
    });

编辑:如果加载有效的图像

$('.buttons').html('');

var range = [];
for (var i = 1; i <=50; i++) range.push(i);

range.forEach(function(i) {
  var img_src = 'http://i.imgur.com/' + i + '.jpg';
  var $img = $("<img>", {
    src: img_src
  });

  $img.on('load', function() {
    $('.buttons').append($img);
  });

  $img.on('error', function() {
  });

});

2
您可以使用addEventListener来添加事件监听器,而不是使用attachEvent。以下是在MDN链接上添加事件监听器的代码:
if (!Element.prototype.addEventListener) {
    var oListeners = {};
    function runListeners(oEvent) {
        if (!oEvent) { oEvent = window.event; }
        for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
            if (oEvtListeners.aEls[iElId] === this) {
                for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
                break;
            }
        }
    }
    Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
        if (oListeners.hasOwnProperty(sEventType)) {
            var oEvtListeners = oListeners[sEventType];
            for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
                if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
            }
            if (nElIdx === -1) {
                oEvtListeners.aEls.push(this);
                oEvtListeners.aEvts.push([fListener]);
                this["on" + sEventType] = runListeners;
            } else {
                var aElListeners = oEvtListeners.aEvts[nElIdx];
                if (this["on" + sEventType] !== runListeners) {
                    aElListeners.splice(0);
                    this["on" + sEventType] = runListeners;
                }
                for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
                    if (aElListeners[iLstId] === fListener) { return; }
                }           
                aElListeners.push(fListener);
            }
        } else {
            oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
            this["on" + sEventType] = runListeners;
        }
    };
    Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
        if (!oListeners.hasOwnProperty(sEventType)) { return; }
        var oEvtListeners = oListeners[sEventType];
        for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
            if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
        }
        if (nElIdx === -1) { return; }
        for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
            if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
        }
    };
}

1

现在最好的方法可能是使用jQuery和jQuery插件imagesLoaded,而不是使用jQuery内置的load()或纯JS。该插件处理了jQuery文档所提到的各种浏览器怪癖,特别是有关缓存图像和重新触发回调(如果新图像的src相同)。只需下载jquery.imagesloaded.min.js,将其添加到<script src="jquery.imagesloaded.min.js"></script>中即可:

$(image).imagesLoaded(function() {
    alert("loaded");
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接