这篇文章发布于 2010年11月19日,星期五,17:36,归类于 jQuery相关。 阅读 538730 次, 今日 38 次 150 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=1259
一、关于滚动显屏加载
常常会有这样子的页面,内容很丰富,页面很长,图片较多。比如说光棍节很疯狂的淘宝商城页面。
或者是前段时间写血本买了个高档耳机的京东商城页面,或者是新浪微博之类。
这些页面图片数量多,而且比较大,少说百来K,多则上兆。要是页面载入就一次性加载完毕。乖乖,估计黄花都变成黄花菜了。所以,我们得做点什么,避免这种糟糕的状况发生。目前很流行的做法就是滚动动态加载,显示屏幕之外的图片默认是不加载的,随着页面的滚动,这个要显示图片的区域进入了浏览器可是窗口范围,则触发图片的加载显示。这种做法的好处是,一是页面加载速度快(浏览器转啊转的圈圈或是进度条很快就玩完了),二是节约了流量,因为不可能每个用户浏览页面时从头滚到尾的。
貌似我上面提到的几个站点就是采用的这种做法,例如,我以迅雷不及掩耳的速度从淘宝商城首页截下来的已触发滚动加载但是未加载完毕的图片:
这是提高前端性能,优化页面加载速度很实用的做法。看上去这种技巧有些技术门槛,其实很简单的。我们需要一个滚动事件,然后判断元素是否在浏览器窗口,然后,显示图片(或是其他元素)就可以啦。我在jQuery库下写了个实现此效果的插件,下面就将简单展示讲解此插件的使用以及滚动动态加载的实现。
二、jQuery滚动加载插件scrollLoading
虽然只有几十行代码,但是为了方便使用,我还是将其插件化了。插件名为jquery.scrollLoading.js,您可以狠狠地点击这里下载(右键 – [目标|链接]另存为),或是点击这里下载mini压缩版的。
demo
您可以狠狠地点击这里:jQuery滚动加载图片等demo,如果您的网速是在贫困线上挣扎,可以慢慢拖动滚动条,就可以很清楚的看到滚动加载的效果了;如果您的网速让你引以为豪,哥,你需要很快的拖动滚动条才能瞥见效果。效果类似下面:
demo页面中似乎有段破坏和谐的HTML片段,那是动态加载HTML后的效果,也就是说,此scrollLoading不仅可以用来滚动加载图片,Ajax load页面什么的也是可以的。
三、scrollLoading使用
不管怎样,首先调用jQuery库文件,还有jquery.scrollLoading.js,您可以直接在页面的某处添上如下的代码:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script> <script type="text/javascript" src="http://www.zhangxinxu.com/study/js/mini/jquery.scrollLoading-min.js"></script>
此插件的方法名就是scrollLoading,所以,直接:包装器.scrollLoading();
就可以实现滚动加载效果了,简单的吧。如下:
$(".scrollLoading").scrollLoading();
表示所有class为scrollLoading的元素绑定了滚动加载的方法。
当然,不可能真的就如此简单,我们还需要做点小动作的。元素默认是不加载的,那么真正的加载地址显然要预先在元素上放置的,例如新浪微博默认把头像地址绑在了一个自定义的”dynamic-src”属性上,见下图:
在HTML5中,以data-开头的自定义属性都是合法的,且地址可以是图片,页面等。所以,我设定了绑定地址的自定义属性为”data-url”,此属性值设为真实的图片(或页面)地址就可以了。例如下面:
<div class="scrollLoading" data-url="loaded.html">加载中...</div>
会在滚动时加载名为loaded.html的页面,并自动替换里面的内容。
对于常用的图片,还有一点小问题,就是其默认的src图片地址。其src地址不能是真实的图片地址(否则会直接一次性全部加载),也不能是空地址或是坏地址,否则IE浏览器下会出现很惊悚的红叉叉。。我的做法是默认链接的是一个1px * 1px的gif透明图片(大小很小),同时可以透出后面加载中gif动画图片,当滚动加载的时候直接把此gif图片替换掉。于是,对于图片,可能就有类似下面的代码:
<img class="scrollLoading" data-url="http://image.zhangxinxu.com/image/study/head/s180/1.jpeg" src="http://www.zhangxinxu.com/study/image/pixel.gif" width="180" height="180" style="background:url(http://www.zhangxinxu.com/study/image/loading.gif) no-repeat center;" />
四、scrollLoading可选参数
scrollLoading是个很简单很小的插件(无注释YUI compressor min版仅508B),所以参数也很少,就一个(已更新),见下表:
参数 | 默认 | 释义 |
---|---|---|
attr | data-url | 获取元素加载地址的属性名 |
就这些了。此插件只适用于页面默认滚动条的动态加载。对于内部div之类的滚动加载不支持。更新于2012年9月27日:
根据部分同行的要求,现增加两个可选参数,一个为container
表示容器,另一个为callback
表示回调。具体参见下表:
参数 | 默认 | 释义 |
---|---|---|
attr | data-url | 获取元素加载地址的属性名 |
container | $(window) | 滚动的容器。默认为$(window),也就是默认的网页滚动。 |
callback | $.noop | 回调。元素动态加载完毕后执行的回调函数。其中回调函数的上下文this 就是当前DOM元素。注意:如果无法获取元素加载地址,则不执行动态加载,但是会触发回调。在某些需求下,您可以缺省url值,仅仅触发回调。 |
特意做了个container
和callback
参数使用的demo,您可以狠狠地点击这里:普通div元素中的动态滚动加载demo
新demo中绑定JavaScript代码如下:
$(".scrollLoading").scrollLoading({ container: $("#zxxMainCon"), callback: function() { this.style.border = "3px solid #a0b3d6"; } });
五、周五,结语
要下班了,nice!
明天周末,我要去钓鱼。
我感冒了,鼻涕流个不停,难受。
空间近日升级了,20G的月流量已经挺不住了。
最近经常看动漫。
我决定在RSS里面加点广告,评论链接什么的。
//zxx:主人,这是你有屎以来最龌龊的结语了。
恩,对此我举双脚表示赞同。
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=1259
(本篇完)
- 翻译:慢点更好-为何排序比速度更重要? (0.508)
- :after伪类+content内容生成经典应用举例 (0.406)
- CSS overscroll-behavior让滚动嵌套时父滚动不触发 (0.133)
- 浏览器IMG图片原生懒加载loading="lazy"实践指南 (0.125)
- 折腾:瀑布流布局(基于多栏列表流体布局实现) (0.102)
- 梳理:提高前端性能方面的处理以及不足 (0.102)
- 基于用户行为的图片等资源预加载 (0.102)
- 开源移动端元素拖拽惯性弹动以及下拉加载两个JS (0.102)
- jQuery图片文本滚动切换插件jCarousel中文翻译与详解 (0.062)
- 借助CSS Shapes实现元素滚动自动环绕iPhone X的刘海 (0.055)
- 纯CSS实现标题栏、表格头水平滚动垂直不滚动 (RANDOM - 0.031)
post = o.offset().top – contop, post + o.height();
应该改为
post = o.offset().top – contop, posb = post + o.height();
这样的话 底部可见的时候才能显示
改了好像全页面都不显示了
用了jQuery kxbdMarquee在DIV里进行图片滚动,如果是屏幕可见当前图片地址会被替换,但如果屏幕不可见,在向下滚动的过程中DIV同时向左滚动,复制出来的图片地址不会被替换,是JS执行先后顺序的问题么?
第一次不会一次加载,第二次的话又全部把图片都加载了
盼望你的回复
我也发现了这个问题,希望博主解决
这就是传说中的图片lazy loading功能,省流浪,还能增强用户体验。
感谢作者,discuz门户文章终于实现图片滚动加载,省下好多cdn流量,都是钱啊。
不好意思,是我调用的方法的问题,已在视窗里的元素可以正常加载了。
后面貌似发现一些问题。例如有些图片已经在窗口默认足够显示的情况下,还是需要进行滚动事件,浏览器才会显示。
毕竟比是所有的图片都是在可视区域外,可能页面加载完后一开始就处于可视区域。
望能修复下,感谢
不错,确实很有效。
和bootstrap的模态框一起用来显示动态内容很是方便!
可以可以,
IE9一下不能用啊
var contHeight = params.container.height();
if ($(window).get(0) === window) {
contop = params.container.offset().top;
//contop = $(window).scrollTop();
} else {
contop = params.container.offset().top;
}
div滚动条里面 contop = $(window).scrollTop();这判断 和配置里面配置内容好像不对 会最后几张图片出不来 我改成一样的处理 不是很会 先这样改下用着
手机端:
图片是width:100%;height:auto;
图片没加载好 高度会不识别
不滚动页面 图片不加载首屏
页面用了第三方幻灯片插件,发现幻灯片图片不加载
$(“.scrollLoading”).scrollLoading({
container: $(“.location-wrap”),
callback: function() {
}
});
加个容器.location-wrap
不滚动页面 图片不加载首屏(好了)
页面用了第三方幻灯片插件,发现幻灯片图片不加载(好了)
不支持IE8吗? 在IE8下看DEMO也没加载出图片
在与iscoll5 配合使用的时候,发现图片不能正常加载。
好像 iscroll4.25 也不能正常加载~
大大,请问倘若元素是动态加载出来的时候,如京东商品列表这种,$(“.scrollLoading”).scrollLoading()这种事件绑定方式貌似无效,应该怎么解决呢?
你在元素生成之后调用事件
demo中的图貌似都失效了,不给外链了。
能否再完善一下,让加载到属性可选。例如,可以加载到 background-image 中去而不只是 src. 谢谢~
大家冷静一些,都过来,听听楼下的怎么说?!~
Zepto好像不能用,问题地址:http://bbs.csdn.net/topics/391543854。。。
怎么才能让它在Zepto下也可以用???
我竟然在你这里瞎转了半个小时。。。。好吧不是瞎转,学到了很多。
顺便咨询下,真的是顺便,的是顺便,是顺便,顺便,便。。。。。。
http://www.yigeyi.cn 这种样子的站有必要延迟加载么?
请问,tab标签中图片延迟加载失效,需要重新滚动才能正常加载出来
点击 tab 标签时,用 js 加个动作,让屏幕向下滚动1像素。
不明觉厉,顺便说句题外话,看到你网站链接,差点吓尿,差点看成我自己的网址了……
嗯,还有个问题,那种单页面的话,怎么实现分屏加载图片提高第一张大图加载速度?
你好, 请问这个效果可以在wordpress中使用吗?
是不是需要重写 图片img地址 , 我记得以前找过一篇教程,是在wordpress中的function.php中加入一段代码 重写Img属性的
给.zxx_test_list 加 display:none 效果就失效了,为什么了,意味着延迟加载的图片本身必须是显示状态,不能被隐藏
@大海 因为
display:none
获取不到位置。没法调用服务器下面的load.html页面。不知道是什么原因~~
就是没有办法通过加载中… 这样的方式进行页面模板调用~~跪求楼主答复
@嘟嘟宝糖葫芦 load.html需要返回干净的div内容,JS什么的,就不要返回了。
请问楼主,当用php动态输出图片时,为什么就没有效了?
像这样:
echo ” “;
zepto能用吗
这样一来,图片的大小就得实现规定好,如果是手机端响应式设计中,如何处理呢
@上上签 CSS3 object-fit~
有未压缩的版本吗 移动端基于zepto能用吗
张大哥,你现在的博客里面都是广告啊,怎么搞得小女子学习着就被领导以为上班不务正业呢?求抱大腿,求精神补偿
鑫大,如果图片没有设定高度。似乎就无法使用了呢?图片还是一下子显示出来?怎么解决呢?
能不能提前当前屏幕显示的多一些的图片呢?
初始打开页面的时候,src用了1px的占位图,小小滚动的时候全部加载了。但是然后刷新页面的话就一张张随滚动加载,请问博主如何解决呢?
我也是这种情况
请问楼主一般都是在哪里钓鱼?
页面一加载默认图片就被替换掉了,同样的用法怎么样果跟你的Demo不一样。
我试着用自定义属性,然后在callback里加setTimeout处理就可以
普通div元素中的动态滚动加载demo 里面的预加载图片,在div 滚动时候,所有的都没能出来!js有报错
你好,可以使用jsfiddle等类似工具提供demo吗?普通
div
需要指定容器为该div
~博主您好
params.container.bind(“scroll”, loading);
您的这里
和另一个JS冲突咋办呢?
我又加了个 回到顶部的小火箭 JS
它里边有这句
a(window).bind(“scroll”,
冲突了 不能共存 愁人。。
@邱嵩松 我只想说,不科学。或者具体描述下你说的冲突是啥冲突?
http://www.18sucai.com/Upfile/Upjs/201207/228/index.html 这个 您试试 和您的插件 放一起 您的插件会失效
博主,你好! 在上面的文章中看到:在HTML5中,以data- 开头的自定义属性都是合法的, 需要它来保存真实的图片地址,是不是意味着此插件只能在适用于HTML的高级浏览器和IE9+中适用?
@Junny 非也。
你好!最新的js代码貌似有点问题,下面代码
var loading = function() {
var contHeight = params.container.height();
if (params.container.get(0) === window) {
contop = $(window).scrollTop();
} else {
contop = params.container.offset().top;
}
params.container.get(0) === window应该为params.container.get(0) == window才对吧,多了一个等于号
这段也多了一个等于号
//在浏览器窗口内
if (tag === “img”) {
@事理 这里强等于和弱等于都是可以的。
加多一个等号有时候载入失败,不载入还只有那个动画有播放了。把等号去掉很完美。
lazyload就是个渣,你这个用起来爽多了。。。
太棒了,感谢感谢!
对于iframe中的img应该如何控制呢?
比如我有一个
其iframe1中有
哥,我试了好几个,就数你这个最好用。其它的不是伪延迟就是太臃肿. 给你31个赞. Thanks for share!
对于默认链接的是一个1px * 1px的gif透明图片这种,万一请求的图片真是地址也是个无法访问的404的图片呢,结果还是要显示惊悚的x的,所以,为了解决这种问题该怎么办呢,是不是需要判断一下这个data-src的地址是不是可用的,如果不可用再去替换图片地址呢?
@Zz 可以的,维护宇宙和平的任务就交给你了~
ie7与ie8下加载不了真实图片
为什么IE8下真实图片不显示啊,非IE显示正常
你的demo根本加载不了真实图片啊,什么原因
@test 你好,10年的页面,使用的是Google的jQuery地址(访问可能有障碍,你懂的),现在已经改成百度CDN,应该可以显示了。
滚动到面对选项卡,怎么破?
建议为本文增加个标签或者关键词 “延迟加载”方便搜索
加载.html页面老不成功,百思不得其解,盼好心人指点下。