【问题标题】:JavaScript/jQuery event listener on image load IE issues图像加载 IE 问题上的 JavaScript/jQuery 事件侦听器
【发布时间】:2011-09-16 09:42:48
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript jquery dom-events image-load


    【解决方案1】:

    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
    • 它没有正确地冒泡 DOM 树
    • 可以停止为已经存在于浏览器中的图像触发 缓存

    请参阅jQuery docs 了解更多信息。

    【讨论】:

    • 谢谢,这就是我要找的东西
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-10-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多