文章为 surreykong原创,转载要指明出处,来自于 http://surrey.iteye.com
首先允许我F*CK CSDN的博客,在我不知道任何问题的情况下就封了我的博客,连个屁都不放一下,城管还给个收据呢!丫的连城管都不如!
打开淘宝首页和大部分的搜索、商品内容页,等待第一屏加载完毕,这个时候拖住浏览器滚动条迅速拖拽,如果你的网速不够快但是动作够快的话(*_*),会看到图片会一张一张的呈现出来,而不是像普通的页面那样,请求页面的时候就一次性加载完毕。
打开Firefox,开启firebug的网络监控可以看到,当第一屏页面加载完毕之后,只要拖拽浏览器的滚动条到一定位置,新的请求就会发出。
一.图片内容延迟加载的优点和缺点。
优点是如果页面中有大量的图片内容,而用户不一定全部看到时(如:只浏览第一屏的内容),1.可以有效降低浏览器的内存消耗 2.减少服务器的压力和带宽消耗。
缺点是如果浏览器不支持或者关闭了javascript,将不能看到需要延迟加载的内容。
二. 图片内容延迟加载技术分析。
把有图片的标签的HTML放在textarea标签内作为value,或者作为一段HTML的注释,这样可以使浏览器略过分析该HTML,图片也就不会加载了。
在需要加载图片时,只需要通过DOM操作,把处理过的HTML取出来作为指定区域的innerHTML,即可使浏览器立即解释该HTML并且加载其中的媒体/图片内容。
其中加载图片的触发条件是1.当页面滚动时 2.刷新后浏览器停留在滚动条位置时。
三.YUI3的实现
组件化的代码。
调用代码:
HTML代码:
首先允许我F*CK CSDN的博客,在我不知道任何问题的情况下就封了我的博客,连个屁都不放一下,城管还给个收据呢!丫的连城管都不如!
打开淘宝首页和大部分的搜索、商品内容页,等待第一屏加载完毕,这个时候拖住浏览器滚动条迅速拖拽,如果你的网速不够快但是动作够快的话(*_*),会看到图片会一张一张的呈现出来,而不是像普通的页面那样,请求页面的时候就一次性加载完毕。
打开Firefox,开启firebug的网络监控可以看到,当第一屏页面加载完毕之后,只要拖拽浏览器的滚动条到一定位置,新的请求就会发出。
一.图片内容延迟加载的优点和缺点。
优点是如果页面中有大量的图片内容,而用户不一定全部看到时(如:只浏览第一屏的内容),1.可以有效降低浏览器的内存消耗 2.减少服务器的压力和带宽消耗。
缺点是如果浏览器不支持或者关闭了javascript,将不能看到需要延迟加载的内容。
二. 图片内容延迟加载技术分析。
把有图片的标签的HTML放在textarea标签内作为value,或者作为一段HTML的注释,这样可以使浏览器略过分析该HTML,图片也就不会加载了。
在需要加载图片时,只需要通过DOM操作,把处理过的HTML取出来作为指定区域的innerHTML,即可使浏览器立即解释该HTML并且加载其中的媒体/图片内容。
其中加载图片的触发条件是1.当页面滚动时 2.刷新后浏览器停留在滚动条位置时。
三.YUI3的实现
组件化的代码。
//定义包名称
var package = {};
YUI.add('asyncScrollLoader', function(Y) {
var asyncScrollLoader = function(config){
asyncScrollLoader.superclass.constructor.apply(this, arguments);
};
asyncScrollLoader.NAME='asyncscrollloader';
asyncScrollLoader.ATTRS={};
Y.extend(asyncScrollLoader, Y.Widget, {
initializer : function(config) {
//存放延迟加载HTML内容的标签名称, 这里应该是textarea
this.delayLoadElementName = config.elementName;
//标签的class
this.delayLoadClass = config.clsName;
//存放延迟加载HTML内容的标签属性,这里应该是value
this.contentAttribute = config.contentAttribute;
},
bindUI : function() {
var self = this;
//定义当页面滚动时,检测需要加载的位置
Y.on('scroll', function(ev) {
self._delayLoader();
});
},
renderUI : function() { //当组建渲染UI时,即检测分析中的第二种情况:浏览器刷新时记录滚动位置。
this._delayLoader(true);
},
_getNextNode : function() { //获得未加载的下一个节点
var selector = this.delayLoadElementName+'.'+this.delayLoadClass;
var node = Y.one(selector);
return node;
},
_delayLoader : function(isPageInitScroll) {
var viewportHeight = Y.DOM.winHeight(), //当前窗口高度
scrollHeight = Y.DOM.docScrollY(), //当前的垂直滚动位置
viewbottom = viewportHeight + scrollHeight,//当前的视窗最下面的垂直坐标
currentNode = this._getNextNode();
if (currentNode==null) {this._delayLoader=function(){};return;}//当所有节点都已加载完毕时,使自身为空函数。
if (viewbottom>=currentNode.getY()) { //当前的视窗最下面的垂直坐标大于等于未加载的节点垂直位置时,加载内容。
currentNode.get('parentNode').replaceChild(Y.Node.create(currentNode.get(this.contentAttribute)), currentNode);
} else {
return;
}
var self = this;
//延迟100毫秒加载,避免多次检测DOM
if (isPageInitScroll) {setTimeout(function(){self._delayLoader(true);},100);}
}
});
package.asyncScrollLoader = asyncScrollLoader;
}, '1.0.0', {requires: ['widget']});
调用代码:
YUI({modules:{'asyncScrollLoader': {
fullpath: 'asyncScrollLoader.js',
type: 'js',
requires:['widget']
}
}}).use('widget','asyncScrollLoader', function(Y){
Y.on('domready', function() {
var cfg = {
'elementName' : 'textarea',
'clsName' : 'class1',
'contentAttribute' : 'value'
};
new package.asyncScrollLoader(cfg).renderer();
});
});
HTML代码:
<!-- 似乎编辑器不支持放textarea 把()去掉就好了-->
(<)textarea class="class1">
<div><img src="asdf1.jpg" mce_src="asdf1.jpg" alt="" /></div>
<div><img src="asdf2.jpg" mce_src="asdf2.jpg" alt="" /></div>
<div><img src="asdf3.jpg" mce_src="asdf3.jpg" alt="" /></div>
<div><img src="asd4f.jpg" mce_src="asd4f.jpg" alt="" /></div>
<div><img src="asdf5.jpg" mce_src="asdf5.jpg" alt="" /></div>
<div><img src="a6sdf.jpg" mce_src="a6sdf.jpg" alt="" /></div>
<div><img src="a7sdf.jpg" mce_src="a7sdf.jpg" alt="" /></div>
<div><img src="as8df.jpg" mce_src="as8df.jpg" alt="" /></div>
<div><img src="asd9f.jpg" mce_src="asd9f.jpg" alt="" /></div>
<div><img src="asdf10.jpg" mce_src="asdf10.jpg" alt="" /></div>
<div><img src="11asdf.jpg" mce_src="11asdf.jpg" alt="" /></div>
(</)textarea>