jquery实现图片按需延迟加载原理

作者:袖梨 2022-11-14

为什么我们需要图片按需加载?

网站中的图片可以使网站添加不少"色彩", 但大量的图片会使我们打开的速度下降, 但我们又不得不用这些图的时候, 我们可以变相的加载这些图片, 常见与一些列表页啊, 或者大数据的主页啊, 或者 "全是图" 的页面, 那么这个图片加载就显着重要了, 比如 jd,taobao啥的都在用, 所以说 你并不孤单!

数据显示通过按需加载图片可以大大的提高网站的打开速度!

1, 首先我们得改变这些图片的HTML结构, 把图片的 src 换成一个 "1*1" 的透明的gif图片(不要说你不会做这个哦), 然后把图片的真实路径写到图片标签中的一个占位属性, 如: data-src="图片真实路径"; 这一步能保证页面在加载的时候每个图片只加载一个很小的图, 以保证打开速度, 因为真实的路径就没有在 src 属性上, 这里切记, src 不能给空!

2, 用js判断这个图片的位置,并给window绑定 scroll, resize 事件, 如果该图片可见则把真实占位的值替换到图片的 src 上,并删除占位的属性,

代码如下 复制代码

var fn = function(){
$("#id img").each(function() {//遍历所有图片
var othis = $(this),//当前图片对象
top = othis.offset().top - $(window).scrollTop();//计算图片top - 滚动条top
if (top > $(window).height()) {//如果该图片不可见
return;//不管
} else {
othis.attr('src', othis.attr('data-src')).removeAttr('data-src');//可见的时候把占位值替换 并删除占位属性
}
});
}
fn();
$window.scroll(fn).resize(fn);//绑定事件


以上代码摘自 八圆包, 但因让您看的更彻底改过源码, 不是 八圆包的源啊...

3, 其实你这现在就已经ok了, 但你会发现一些能优化的地方, 比如: js代码的优化啊,因为大量的执行 scroll 事件是很不帅的一件事,你得缓存+延迟下, 还有图片在加载中的时候给个loading, 没问题, 这个可以给这个img用css写个loading的背景gif图片;

代码如下 复制代码


img.load{background:url('/images/loading.gif') no-repeat center center;}/*没有加载时loading的效果*/


4, 那个 $("#id img") 是图片选择器, 你可以给图片都加上 class , 然后用 $("img.loadImg") 等, 这样也更方便的只给需要延迟加载的图片加了;

注: 当你把这些玩的很熟的时候你就应该写成插件了, 另这个判断图片可见只是个简单的判断, 如果用户在加载完时直接按的键盘 end 键或者用户打开就在最小面, 那么你的图片一下子全部加载起来, 解决这个问题只需要在判断可见的时候再加深点判断即可, 代码如:

代码如下 复制代码


if ($(window).scrollTop() + $(window).height() >= ($(this).offset().top) && ($(this).offset().top + $(this).height() >= $(window).scrollTop()) { //高级可见
}


是否对SEO有影响

没有影响的, 但要注意的是, 现在百度已经开始大量抓页面的图片, 建议在详情页的时候把产品/商品的首图不采用按需加载, 因为这样加载可能不会被seo/seo.html">搜索引擎捕获到;
网上插件的一个通病

看网上有不少实现图片加载的, 但很多没给出明确的改HTML代码的步骤, 只是用js操作, 经查看源码后发现, 都是在js里把图片的真实路径存起来,如图:

图片延迟加载

但经过控制台网络查看, 这样的会在你js执行之前的所有图片已经请求了, 也就是说没有达到优化的效果!

下面整理一个例子,大家看看

代码如下 复制代码


//css
img.load{background:url('/iamges/loading.gif') no-repeat center center;}/*没有加载时loading的效果*/


/**
* @name 图片懒加载插件
* @description jQuery扩展插件,可制作滚动加载,点击加载等,依赖msc,jQuery,msc.event,目前只对window上操作
* @version 1.0
* @author xieliang
* @demo
* 1, 延迟加载
* $("#id img.imgLoad").imgLoad();//默认真实图片路径在 data-src 里, 默认为淡入
* 2, 修改真实图片路径
* $("img.imgLoad").imgLoad({attr:"data-img-src"});
* 3, 修改淡入效果
* $("img").imgLoad({effect:"show"});//没有淡入效果
* 4, 自定义事件
* $("img").imgLoad({event:"xieliang"});//定义事件名
* 在需要的地方 $("img").trigger("xieliang");//触发加载
* 5, 设置屏幕偏移, 支持 正,负
* $("img").imgLoad({threshold:-100});
*/
;(function(a) {
"use strict";
a.fn.imgLoad = function(config) {
var self = this;
if (!self.length || self[0].nodeName.toLowerCase() !== "img") {//如果选择器没有 或者 不是图片则返回自己www.111com.net
return self;
};
var conf = a.extend({}, a.fn.imgLoad.defaults, config || {});//合并
var cache = {};//存放图片对象
var imgLength = self.length;//总图片个数
var imgI = 0;//已加载的图片个数
if ("scroll" === conf.event) {//如果是滚动事件
var scroll = new msc.event("scroll", 0);//创建0延迟的滚动
scroll.add("imgLoad", function(obj) {
for (var item in cache) {//运行图片对象缓存
// if (obj.scrollTop + obj.height >= (cache[item].offset().top + conf.threshold)) {//如果该图片可见
if (obj.scrollTop + obj.height >= (cache[item].offset().top + conf.threshold) && (cache[item].offset().top+cache[item].height() >= obj.scrollTop)) {//高级可见
cache[item].trigger("imgLoad");//触发当前图片的加载事件
};
};
if (imgI >= imgLength) {//如果已加载大于等于总数
imgLength = imgI = cache = null;//清
msc.event.resize.remove("imgLoad");//移除resize事件
return false;//返回false移除scroll事件
};
});
msc.event.resize.add("imgLoad", function() { //设置resize时触发事件
scroll.trigger("imgLoad");
});
setTimeout(function() {
scroll.trigger("imgLoad"); //默认加载触发下,解决可能滚动条加载完成时不在顶部而不加载图片
}, 50);
};
return self.each(function(i) {//遍历所有图片
var $img = $(this);
cache[i] = $img;//把图片填进缓存
$img.one("imgLoad",//绑定一次性事件
function() {
if(!this['_imgLoad']){//为了配合tab组件可防止重复加载
this['_imgLoad'] = 1;
$("").bind("load",//创建个img来预加载
function() {
$img.hide().attr("src", $img.attr(conf.attr))[conf.effect]().removeAttr(conf.attr);//显示该图片
}).attr("src", $img.attr(conf.attr));
}
delete cache[i];//删除缓存里的
imgI++;//让已加载数自增下
});
if ("scroll" !== conf.event) {//如果不是滚动事件
$img.one(conf.event,//绑定一次性事件触发
function() {
if (cache[i]) {//如果缓存存在则视为没有加载
cache[i].trigger("imgLoad");//触发加载
};
});
};
});
};

a.fn.imgLoad.defaults = { //默认配置
attr: "data-src",//连接占位
effect: "fadeIn",//效果
event: "scroll",//事件
threshold:0//偏移,可为正/负数
};
}(jQuery));

相关文章

精彩推荐