刚刚改进了一下某个页面的图片lazyload功能。
原先是用jquery的lazyload插件的标准方式做的。有一个缺点是脚本不开启时图片都不显示了。
解决方法也不难,就是同时插一个noscript标签。lazyload插件官网给出的解决方案也是如此。
<img class="lazy" src="img/grey.gif" data-original="img/example.jpg" width="640" heigh="480">
<noscript><img src="img/example.jpg" width="640" heigh="480"></noscript>
不过这个方式带来双份的代码,且还要额外的样式表切换(避免无脚本时也出现用于有脚本时的占位图片)。
其实脚本本来就可以做任何事情,我们完全可以直接提取noscript里的部分。以下是代码示例
1. 模板部分(Jade):
span.thumb
if (imgSrc)
if index >= 10
noscript: img(src=imgSrc, alt='')
else
img(src=imgSrc, alt='')
else
img(src='default.png', alt='')
注:暂时设定了前10项不用lazyload。
2. 脚本部分:
script(src="jquery.lazyload.min.js")
script
$(function(){
var imgs = $('span.thumb:has(noscript:contains(img))')
$(window).on('scroll', function(evt){
var showImgs = imgs.filter(':in-viewport')
showImgs.html(function(){ return $(this).find('noscript').text() })
imgs = imgs.not(showImgs)
})
})
注:
:has(selector)是jQuery支持的伪类,表示子代元素必须匹配指定selector。
:contains(text)也是jQuery支持的伪类,表示元素包含指定的文本。因为noscript里的部分被作为文本节点,所以这里其实是比较随意的,比如<noscript>sex img</noscript>也会匹配。
:in-viewport是lazyload插件扩展的伪类,表示元素是否处于窗口可见区域。
当然以上的方式的缺点就是无法使用lazyload插件的标准方式和其他功能(比如渐现),但这足以作为一个PoC,我有空完善下再给lazyload作者发个pull request(或者哪位读者愿意做这个事情也很好啊)。