【问题标题】:jQuery or Javascript check if image loadedjQuery 或 Javascript 检查图像是否加载
【发布时间】:2014-01-04 00:35:26
【问题描述】:

我知道 Stackoverflow 上有很多这样的内容,但我还没有在最新版本的 jquery (1.10.2) 中找到适合我的内容。

我试过了:

$(".lazy").load(function (){}

但我相信经过一些研究,使用.load 来检测图像负载在 jQuery 1.8 中已被弃用。我需要做的是在加载图像后触发图像调整大小功能。我无法控制 HTML,目前我必须通过 jQuery 添加图像尺寸,方法是在页面加载后附加一个属性(通过.attr()),以便我可以使用lazyload js。

问题是我需要一种准确的方法来推迟我所有的各种脚本,直到图像正确加载,否则函数有时会在每个图像加载之前触发。我曾尝试使用$(window).load(function (){});,但有时它仍会在每张图片加载之前触发。

【问题讨论】:

  • 你确定$(window).load()吗?我从来没有遇到过这个问题,并且来自 jQuery 文档:“当页面完全加载时运行一个函数,包括图形。”
  • 你可以使用 $(document)ready(); 来检查 DOM 是否准备就绪;
  • 我将重新运行我的测试并仔细检查我对 window.load 是否正确
  • “但我相信经过一些研究,这在 jQuery 1.8 中已被贬值” 应该弃用什么?
  • 更新问题。我的意思是我认为 .load 检测图像加载自 1.8 以来不起作用

标签: javascript jquery


【解决方案1】:

在等待加载多张图片的情况下:

var images = $("#div-with-images img");
var unloaded = images.length;
images.on('load', function(){
  -- unloaded;
  if (!unloaded) {
    // here all images loaded, do your stuff
  }
});

【讨论】:

    【解决方案2】:

    图像对象还有一个有用的.complete 属性,如果您在附加任何事件侦听器之前已经设置了<img>.src,则可以使用它:

    var img=document.getElementById('myimg');
    var func=function(){
        // do your code here
        // `this` refers to the img object
    };
    if(img.complete){ 
        func.call(img);
    }
    else{ 
        img.onload=func; 
    }
    

    参考:http://www.w3schools.com/jsref/prop_img_complete.asp

    【讨论】:

    • 这正是我需要捕捉通过$(xx).html() 调用加载的图像的结尾
    【解决方案3】:

    我会给需要这个约束的图像一个像mustLoad这样的类,其中:

    <img class="mustLoad" src="..." alt="" />
    

    然后创建一个通用的图片加载处理函数,如:

    $('img.mustLoad').on('load',function(){
            /* Fire your image resize code here */
    });
    

    编辑

    作为对您的 cmets 关于弃用上述 .load() 的回应,.load() 已被弃用,而在 onLoad 事件和 Ajax 加载之间支持.on('load') to reduce ambiguity

    【讨论】:

      【解决方案4】:

      我需要做的是在加载图像后触发图像调整大小功能。

      您确定需要加载图像吗?在调整图片大小之前等待图片加载可能会导致页面布局发生较大的跳跃,尤其是当图片具有较大的文件大小时,例如动画 GIF。

      通常,对于图像调整大小,您只需要知道图像的固有尺寸即可。虽然没有事件可以告诉您这一点,但轮询图像以获取数据很容易。像这样的东西可能特别有效:

      <img src="..." data-resizeme="123" />
      
      (function() {
          var images, l, i, tmp;
          if( document.querySelectorAll) {
              images = [].slice.call(document.querySelectorAll("img[data-resizeme]"),0);
          }
          else {
              tmp = document.getElementsByTagName("img");
              images = [];
              // browser compatibility is fun!
              for( i=tmp.length-1; i>=0; i--) {
                  if( tmp[i].getAttribute("data-resizeme")) images.unshift(tmp[i]);
              }
          }
      
          for( i=images.length-1; i>=0; i--) {
              images[i].onload = resizeImage;
              images[i].onerror = cancelImageResize;
          }
          var timer = setInterval(function() {
              for( i=images.length-1; i>=0; i--) {
                  if( images[i].width) {
                      resizeImage.call(images[i]);
                      images[i].onload = null;
                      cancelImageResize.call(images[i]);
                  }
              }
              if( images.length == 0) clearInterval(timer);
          },100); // adjust granularity as needed - lower number is more responsive.
      
          function cancelImageResize() {
              var i;
              for( i=images.length-1; i>=0; i--) {
                  if( images[i] == this) {
                      images.splice(i,1);
                      break;
                  }
              }
          }
      
          function resizeImage() {
              console.log("Image "+this.src+" is "+this.width+"x"+this.height);
          }
      })();
      

      希望这会有所帮助!

      【讨论】:

      • 是 data-resizeme="123" - 特别是 123,我希望它调整到的图像大小?
      • 你可以做到。在resizeImage 函数中,使用parseInt(this.getAttribute("data-resizeme"),10) 获取值,然后应用它。关键是在那里有一个属性。你用它来做什么取决于你。
      • 用setInterval做一个轮询函数是非常非常糟糕的,这是管理异步函数最糟糕的方式,而是使用回调系统。
      • @DarkoRomanov Erm...您如何建议轮询没有关联事件处理程序的东西?
      • 该事件是 Image DOM 对象的 onload,您只需要一个包含每个图像的 url 的数组和一个指向当前图像的简单指针。当图像完成加载时,您再次调用相同的加载函数,增加您的指针。见小提琴jsfiddle.net/93Q7Y
      【解决方案5】:

      我通常这样做:

      var image = new Image();
      image.onload = function () {
         console.info("Image loaded !");
         //do something...
      }
      image.onerror = function () {
         console.error("Cannot load image");
         //do something else...
      }
      image.src = "/images/blah/foo.jpg";
      

      请记住,加载是异步的,因此您必须在 onloadonerror 事件中继续执行脚本。

      【讨论】:

      • 如果我正在加载大量图像,我认为我需要引用所有图像路径?
      • 嗯,这取决于你的想法。如果该过程需要在开始之前加载所有图像,那么是的,您必须将它们全部加载。
      • 如果我的列表是动态的,我可以创建一个变量来查看所有图像的 src 属性,然后以这种方式应用它?
      • 是的,当然。静态数组只是一个例子,你可以在启动前读取所有的 src,然后启动 preload 函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 2011-11-12
      • 2016-01-20
      • 1970-01-01
      相关资源
      最近更新 更多