简体   繁体   English

所有浏览器的图像加载时的JavaScript / jQuery事件监听器

[英]JavaScript/jQuery event listener on image load for all browsers

I am looking for a way to implement this for as many browsers as possible: 我正在寻找一种方法来实现尽可能多的浏览器:

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

This didn't work in IE so I googled and found out that IE's lower than 9 do not support .addEventListener() . 这在IE中不起作用所以我用Google搜索并发现IE低于9不支持.addEventListener() I know there is a jQuery equivalent called .bind() but that doesn't work on an Image() . 我知道有一个名为.bind()的jQuery等价物,但它不适用于Image() What do I have to change for this to work in IE too? 为了在IE中工作,我还需要改变什么?

IE supports attachEvent instead. IE支持attachEvent。

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

With jQuery, you can just write 使用jQuery,你可以写

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

When it comes to events, if you have the possibility of using jQuery I would suggest using it because it will take care of browser compatibility. 当涉及到事件时,如果你有可能使用jQuery我建议使用它,因为它将负责浏览器兼容性。 Your code will work on all major browser and you don't have to worry about that. 您的代码适用于所有主流浏览器,您不必担心这一点。

Note also that in order to the load event being fired in IE, you need to make sure the image won't be loaded from the cache, otherwise IE won't fire the load event. 另请注意,为了在IE中触发加载事件,您需要确保不会从缓存加载图像,否则IE将不会触发加载事件。

To do this, you can append a dummy variable at the end of the url of your image, like this 为此,您可以在图像的URL末尾附加一个虚拟变量,就像这样

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

Some known issues using the jQuery load method are 使用jQuery加载方法的一些已知问题是

Caveats of the load event when used with images 与图像一起使用时加载事件的注意事项

A common challenge developers attempt to solve using the .load() shortcut is to execute a function when an image (or collection of images) have completely loaded. 开发人员尝试使用.load()快捷方式解决的常见挑战是在图像(或图像集合)完全加载时执行函数。 There are several known caveats with this that should be noted. 应该注意有几个已知的警告。 These are: 这些是:

  • It doesn't work consistently nor reliably cross-browser 它不能一致地工作,也不能可靠地跨浏览器
  • It doesn't fire correctly in WebKit if the image src is set to the same src as before 如果图像src设置为与之前相同的src,则它在WebKit中无法正确触发
  • It doesn't correctly bubble up the DOM tree 它没有正确地冒泡DOM树
  • Can cease to fire for images that already live in the browser's cache 可以停止为已经存在于浏览器缓存中的图像触发

See the jQuery docs for more info. 有关更多信息,请参阅jQuery文档

You have to use .attachEvent() rather than .addEventListener() . 您必须使用.attachEvent()而不是.attachEvent() .addEventListener()

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

new Image basically returns an <img> tag, so you can code in jQuery like: http://jsfiddle.net/pimvdb/LAuUR/1/ . new Image基本上返回一个<img>标签,因此您可以在jQuery中编写代码: http//jsfiddle.net/pimvdb/LAuUR/1/

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

EDIT: in case of loading valid images 编辑:在加载有效图像的情况下

$('.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() {
  });

});

You can use attachEvent , but I would rather prefer you would add the addEventListener listener yourself. 你可以使用attachEvent ,但我宁愿你自己添加addEventListener监听器。 Here is the code on that MDN link for adding the event listener: 以下是用于添加事件侦听器的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); }
        }
    };
}

The best way to do it now is probably to use jQuery and the jQuery plugin imagesLoaded instead of jQuery's built-in load() or plain JS. 现在最好的方法是使用jQuery和jQuery插件imagesLoaded而不是jQuery的内置load()或普通JS。 The plugin takes care of the various browser quirks that the jQuery docs refer to, namely regarding cached images and re-firing the callback if the new image's src is the same. 该插件负责jQuery文档引用的各种浏览器怪癖,即关于缓存的图像,并在新图像的src相同时重新触发回调。 Just download jquery.imagesloaded.min.js , add it in with <script src="jquery.imagesloaded.min.js"></script> and you're good to go: 只需下载jquery.imagesloaded.min.js ,用<script src="jquery.imagesloaded.min.js"></script>添加它,你就可以了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM