var docElement = document.compatMode === 'BackCompat' ? document.body : document.documentElement; //如果是非标准,则是document.body,不然是document.documentELement,计算clientHeight用到 var defaults = { lazyAttr: 'lazy_src',//保存SRC的自定义属性 upBuffer: 100,//向上缓冲的距离 downBuffer: 100,//向下缓冲的距离 bufferTime: 100,//滚动时缓冲的时间 defultSrc: ''//初始化时的默认图片 } function getTop(el){ if(!el) return null; var element = el, offsetTop = element.offsetTop; while(element = element.offsetParent){ offsetTop += element.offsetTop; } return offsetTop; } function LazyLoad(sel, options){//sel为需要懒加载的选择器字符串 var that = this; this.opt = $.extend(defaults, options); this.el = [];//元素 this.elList = [];//包含元素,src的对象数组 this.lazyList = []; this.sel = sel; this.gt = null;//计时器 $(function(){ that.el = $(that.sel).filter('[' + that.opt.lazyAttr + ']'); that.el.forEach(function(item, index){//item是原生dom that.opt.defultSrc && $(item).attr('src', that.opt.defultSrc); var lazySrc = $(item).attr(that.opt.lazyAttr); lazySrc && that.elList.push({ el: $(item), src: lazySrc }); }) that.num = that.elList.length; that.loadEl(); that.bindEvent(); }) } LazyLoad.fn = LazyLoad.prototype; LazyLoad.fn.bindEvent = function(){ var that = this; $(window) .bind('resize', function(){ that.lazyLoadEl(); }) .bind('scroll', function(){ that.lazyLoadEl(); }) } LazyLoad.fn.getlazyList = function(){ var that = this, offset = window.scrollY,//向上滚动的距离 beforeOffset = offset - that.opt.upBuffer, visiOffset = offset + docElement.clientHeight + that.opt.downBuffer;//可视区域的距离 that.lazyList = that.elList.filter(function(item, index){ var elNow = item.el.get(0); elNow.top = getTop(elNow); return !elNow.loaded && elNow.top < visiOffset && elNow.top > beforeOffset; }) return that.lazyList; } LazyLoad.fn.lazyLoadEl = function(){ var that = this; clearTimeout(that.gt); that.gt = setTimeout(function(){ that.loadEl(); }, that.opt.bufferTime); } LazyLoad.fn.loadEl = function(){ var that = this; if(that.num < 1 || that.getlazyList().length < 1){ clearTimeout(that.gt); return; } $(that.lazyList).forEach(function(item, index){ item.el.attr('src', item.src); item.loaded = true;//已经设置过src的再次计算到就过滤掉 that.num--; }) }