23

我正在寻找一种为尽可能多的浏览器实现此功能的方法:

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

这在 IE 中不起作用,所以我搜索了一下,发现 IE 低于 9 不支持.addEventListener(). 我知道有一个等效的 jQuery .bind(),但它不适用于Image(). 我必须改变什么才能在 IE 中工作?

4

5 回答 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() 快捷方式解决的一个常见挑战是在图像(或图像集合)完全加载时执行一个函数。应该注意几个已知的警告。这些都是:

  • 它不能始终如一地工作,也不能可靠地跨浏览器
  • 如果图像 src 设置为与以前相同的 src,它不会在 WebKit 中正确触发
  • 它没有正确地冒泡 DOM 树
  • 可以停止对已经存在于浏览器缓存中的图像进行触发

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

于 2011-09-16T09:47:04.103 回答
8

你必须使用.attachEvent()而不是.addEventListener().

if (image.addEventListener) {
  image.addEventListener('load', function() {
       /* do stuff */ 
  });
} else {
  // it's IE!
  image.attachEvent('onload', function() {
    /* do stuff */
  });
}
于 2011-09-16T09:46:20.777 回答
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() {
  });

});
于 2011-09-16T09:46:40.870 回答
2

您可以使用attachEvent,但我宁愿您addEventListener自己添加侦听器。这是该 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); }
        }
    };
}
于 2011-09-16T09:48:52.227 回答
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");
});
于 2013-01-12T06:48:59.077 回答