引:
目前流行的页面延迟加载以及渲染组件,参考 kissy 所写,练习一下YUI3模块编写。
原理:
1.对于目前屏幕以外的图片src设置为同一占位图片,监听窗体滚动,当图片进入可见区域,替换src为真实地址。
2.对于屏幕外延迟渲染的html存放在隐藏(visibility:hidden)的textarea中,并且该textarea占据本该渲染的位置,监控窗体滚动,当textarea进入可见区域,将该textarea内的value,插入到textarea之前,并删除掉textarea。
PS:近来重构 kissy 的一些注意点:
1.注意 textarea 内容包含脚本时的情况,由于非firefox浏览器不会自动触发其中的脚本,不应该在将html插入到textarea的父结点后,在父节点下搜寻script 节点对其内容进行触发(会使原本存在的脚本再次执行),而应该对textarea的内容html进行正则表达式 script 抽取,并对html过滤script后再插入容器,这样也避免了浏览器判断。
2.callBack 没有意义,我们关心的是什么时候 textarea 的内容会被渲染到 dom 树中,随之进行一些 关联textarea部分的内容 组件初始化操作,而不需要已经存在于dom数中的节点何时会在用户的预查区域(确实需要的话可将该节点内容放入textarea中做延迟渲染)。
3.触发渲染事件注意使用setTimeout异步,由于可能用户在当前位置刷新,这时在初始化 datalazyloader 时就会发生渲染事件,那么在初始化后的捕捉就没有意义了:
var l=new lazyloader();//可能一开始就触发了render事件,这时尚没有on l.on("render",function(){});
代码结构:
/** YUI3数据延迟加载组件 修改自:http://code.google.com/p/kissy/ **/ YUI.add('dataLazyLoad', function (Y) { function DataLazyLoad(config) { //实例或工厂方法都可以 } DataLazyLoad.NAME = "dataLazyLoad"; DataLazyLoad.ATTRS = { containers: { //Y.all形式参数统一化处理 setter: function (nodes) {} } }; Y.extend(DataLazyLoad, Y.Base, { //得到可见的文档纵轴下限 _getLowerThreshold: function () {}, //初始化函数 initializer: function (cfg) { //即将由于延迟加载而显示的图片元素 //初始屏下的才惰性加载 //初始屏下的才惰性加载,其他立即处理 }, //根据滚动条位置开始延迟加载 _loadByThreshold: function () {}, // the destroy() lifecycle phase destructor: function () {} }); Y.DataLazyLoad = DataLazyLoad; });
调用:
YUI({ modules: { dataLazyLoad: { fullpath: 'datalazyload.js', requires: ['event', 'base', 'node', 'test'] } } }).use("dataLazyLoad", function (Y) { var dataLazyLoad = new Y.DataLazyLoad({ //Y.all参数格式 containers: "body" }); //即将由于延迟加载而显示的图片元素 dataLazyLoad.on("lazyShow", function (e) { var img = e.details[0]; if (window.console) console.log(img); }); });