【问题标题】:stand-alone lazy loading images (no framework based)独立的延迟加载图像(不基于框架)
【发布时间】:2017-12-22 02:40:26
【问题描述】:

我管理的网站本质上必须在页面上加载大量图像和内容。我们已尽可能减少元素和图形布局图像的数量,因此我们现在正在寻找增加浏览器页面负载的方法。

有谁知道不需要jQuery等框架的延迟加载图像的代码?

【问题讨论】:

    标签: javascript image lazy-loading optimization


    【解决方案1】:

    这是我自己的。玩得开心。

    已测试: IE 5.5+、FF 2+、Chrome、Opera 9.6+

    用法:

    1. 您的延迟加载图像应该在 thumb 属性中包含它们的真实 src

    2. 只需在内联或外部包含 javascript 文件。

    3. 如果您不想在整个页面上使用它,可以这样做:

       LazyImg().destroy(); // stop global fetching
       LazyImg("watch-only-this-div");
      

      注意:当您包含文件时,已经创建了一个全局实例来监视整个文档。您需要先停止它并启动您自己的实例。

      1. 为预取设置自定义偏移量(应在折叠下方多远的位置获取图像)

         // watch the whole document
         // prefetch offset: 300px
         LazyImg(document, 300); 
        

    代码:

    //
    //  LAZY Loading Images 
    //
    //  Handles lazy loading of images in one or more targeted divs, 
    //  or in the entire page. It also keeps track of scrolling and 
    //  resizing events, and removes itself if the work is done. 
    //
    //  Licensed under the terms of the MIT license.
    //
    //  (c) 2010 Balázs Galambosi
    //
    
    (function(){
    
    // glocal variables
    var window    = this, 
        instances = {},
        winH;
    
    // cross browser event handling
    function addEvent( el, type, fn ) {
      if ( window.addEventListener ) {
        el.addEventListener( type, fn, false );
      } else if ( window.attachEvent ) {
        el.attachEvent( "on" + type, fn );
      } else {
        var old = el["on" + type];
        el["on" + type] = function() { old(); fn(); };
      }
    }
    
    // cross browser event handling
    function removeEvent( el, type, fn ) {
      if ( window.removeEventListener ) {
        el.removeEventListener( type, fn, false );
      } else if ( window.attachEvent ) {
        el.detachEvent( "on" + type, fn );
      }
    }
    
    // cross browser window height
    function getWindowHeight() {
      if ( window.innerHeight ) {
        winH = window.innerHeight;
      } else if ( document.documentElement.clientHeight ) {
        winH = document.documentElement.clientHeight;
      } else if ( document.body && document.body.clientHeight ) {
        winH = document.body.clientHeight;
      } else {        // fallback:
        winH = 10000; // just load all the images
      }
      return winH;
    }
    
    // getBoundingClientRect alternative
    function findPos(obj) {
      var top  = 0;
      if (obj && obj.offsetParent) {
        do {
          top += obj.offsetTop || 0;
          top -= obj.scrollTop || 0;
        } while (obj = obj.offsetParent); // 
        return { "top" : top };
      }
    }
    
    // top position of an element
    var getTopPos = (function() {
      var dummy = document.createElement("div");
      if ( dummy.getBoundingClientRect ) {
        return function( el ) { 
          return el.$$top || el.getBoundingClientRect().top;
        };
      } else {
        return function( el ) { 
          return el.$$top || findPos( el ).top;
        };
      }
    })();
    
    // sorts images by their vertical positions
    function img_sort( a, b ) {
      return getTopPos( a ) - getTopPos( b );
    }
    
    // let's just provide some interface 
    // for the outside world
    var LazyImg = function( target, offset ) {
    
      var imgs,    // images array (ordered)
          last,    // last visible image (index)
          id,      // id of the target element
          self;    // this instance
    
      offset = offset || 200; // for prefetching
    
      if ( !target ) {
        target = document;
        id = "$document";
      } else if ( typeof target === "string" ) {
        id = target;
        target = document.getElementById( target );
      } else {
        id = target.id || "$undefined";
      }
    
      // return if this instance already exists
      if ( instances[id] ) {
        return instances[id];
      }
    
      // or make a new instance
      self = instances[id] = {
    
        // init & reset
        init: function() {
          imgs = null;
          last = 0;
          addEvent( window, "scroll", self.fetchImages );
          self.fetchImages();
          return this;
        },
    
        destroy: function() { 
          removeEvent( window, "scroll", self.fetchImages );
          delete instances[id];
        },
    
        // fetches images, starting at last (index)
        fetchImages: function() {
    
          var img, temp, len, i;
    
          // still trying to get the target
          target = target || document.getElementById( id );
    
          // if it's the first time
          // initialize images array
          if ( !imgs && target ) {
    
            temp = target.getElementsByTagName( "img" ); 
    
            if ( temp.length ) {
              imgs = [];
              len  = temp.length;
            } else return;
    
            // fill the array for sorting
            for ( i = 0; i < len; i++ ) {
              img = temp[i];
              if ( img.nodeType === 1 && img.getAttribute("thumb") ) {
    
                  // store them and cache current
                  // positions for faster sorting
                  img.$$top = getTopPos( img );
                  imgs.push( img );
              }
            }
            imgs.sort( img_sort );
          }
    
          // loop through the images
          while ( imgs[last] ) {
    
            img = imgs[last];
    
            // delete cached position
            if ( img.$$top ) img.$$top = null;
    
            // check if the img is above the fold
            if ( getTopPos( img ) < winH + offset )  {
    
              // then change the src 
              img.src = img.getAttribute("thumb");
              last++;
            }
            else return;
          }
    
          // we've fetched the last image -> finished
          if ( last && last === imgs.length )  {
            self.destroy();
          }
        }  
      };
      return self.init();
    };
    
    // initialize
    getWindowHeight();
    addEvent( window, "load",   LazyImg().fetchImages );
    addEvent( window, "resize", getWindowHeight       ); 
    LazyImg();
    
    window.LazyImg = LazyImg;
    
    }());
    

    【讨论】:

    • 抱歉,img 上的“thumb”属性是什么意思?
    • &lt;img src="pixel.gif" thumb="real_image_to_be_loaded.jpg"&gt;。如果标记保持不变,浏览器通常会下载图像。
    • 嗯,谢谢你的代码,麻烦的是机器人会到处看到 pixel.gif 而不是实际的文件,从而错误地索引它们?
    • 从你的代码开始,然后全部重写我做了一个类似的惰性加载器:github.com/fasterize/lazyload
    • 是的,为了简单起见,您可以限制滚动事件处理程序并检查每个图像的位置。我的设计用于处理大量图像,通过按位置对图像进行排序来预先完成大部分工作。
    【解决方案2】:

    “thumb”在使用 XHTML 时无效。我将其更改为“标题”,它似乎工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多