关于图像加载 IE 问题的 JavaScript/jQuery 事件侦听器

发布于 2024-12-05 02:25:08 字数 364 浏览 2 评论 0原文

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

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

这在 IE 中不起作用,所以我用 google 搜索并发现 IE 低于 9 不支持 .addEventListener()。我知道有一个名为 .bind() 的 jQuery 等效项,但它不适用于 Image()。我需要更改什么才能使其在 IE 中也正常工作?

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(). I know there is a jQuery equivalent called .bind() but that doesn't work on an Image(). What do I have to change for this to work in IE too?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

む无字情书 2024-12-12 02:25:08

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

  • 跨浏览器工作不稳定且不可靠
  • 如果图像 src 设置为
    与之前相同的 src
  • 它没有正确地冒泡 DOM 树
  • 可以停止触发已存在于浏览器中的图像
    缓存

有关详细信息,请参阅 jQuery 文档

IE supports attachEvent instead.

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

With jQuery, you can just write

$(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. 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.

To do this, you can append a dummy variable at the end of the url of your image, like this

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

Some known issues using the jQuery load method are

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. 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
  • It doesn't correctly bubble up the DOM tree
  • Can cease to fire for images that already live in the browser's
    cache

See the jQuery docs for more info.

半枫 2024-12-12 02:25:08

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

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

You have to use .attachEvent() rather than .addEventListener().

if (image.addEventListener) {
  image.addEventListener('load', function() {
       /* do stuff */ 
  });
} else {
  // it's IE!
  image.attachEvent('onload', function() {
    /* do stuff */
  });
}
丑丑阿 2024-12-12 02:25:08

您可以使用 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); }
        }
    };
}

You can use attachEvent, but I would rather prefer you would add the addEventListener listener yourself. Here is the code on that MDN link for adding the event listener:

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); }
        }
    };
}
国际总奸 2024-12-12 02:25:08

new Image 基本上返回一个 标签,因此您可以在 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() {
  });

});

new Image basically returns an <img> tag, so you can code in jQuery like: 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() {
  });

});
Oo萌小芽oO 2024-12-12 02:25:08

现在最好的方法可能是使用 jQuery 和 jQuery 插件 imagesLoaded 而不是 jQuery 的内置load() 或纯 JS。该插件负责处理 jQuery 文档提到的各种浏览器怪癖,即关于缓存图像并在新图像的 src 相同时重新触发回调。只需下载 jquery.imagesloaded.min.js,添加将其与 放在一起就可以了:

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

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. 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. Just download jquery.imagesloaded.min.js, add it in with <script src="jquery.imagesloaded.min.js"></script> and you're good to go:

$(image).imagesLoaded(function() {
    alert("loaded");
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文