• 【项目分析】设计一种前端数据延迟加载的jQuery插件(2)


    背景

    最近看到很多网站都运用到了一种前端数据延迟加载技术,包括淘宝,新浪网等等,这样做的目的可以使得一些未显示的图片随 着滚动条的滚动进行延迟显示。

    好处显而易见,可以减少前端对于图片的Http请求,减轻对于服务器的压力,对于长篇并且大批量的图片的网页很有帮助。

    详细分析

    1. 今天就来介绍如何设计这样的一种jQuery插件。

    jQuery官方也开放一个Lazyload插件,但是用了一下,发现它 有些问题,在网页加载的时候(具体地址可以参考这个Demo:http://www.appelsiini.net/projects/lazyloa d/enabled_container.html),利用HttpWatch可以发现,六张图片其实都有在下载,只是在下载过程中,他会将src路径转换 为orginal路径,当转换为orginal路径时,http请求就会被终止(Aborted),如果拉动滚动条,它会把original路径再转换为src的 路径。同时可以在HttpWatch中观察到它获取得到一个206的HttpCode,206协议是Partial Content,也就是服务端只接收到了部分Http请求。因此,在图片尺寸比较大的情况下,图片加载较慢,因此请求会被拦截,并且保留客户端数据,在下次Img标签加载Load方法的时候,可以继续请求图片数据。HttpWatch查看效果如下:

    图上有3个图片的Http请求被终止。

    2. 如果我想让它在网页加载的时候,只要没显示的图片,就不要让它去调用请求,那么该如何实现呢?那么开始以下我的设计。

    首先,我们考虑到一个Img标签如果具有src属性,并且已经在 Html加载出来的时候,会自动去请求服务端,甚至<img src=” ” />都会去请求服务端。所以,在你加载具有src路径的图片之前,必须让它不被加载,我这里使用到的一个技巧,将包含Img 标签的DOM元素全仍进一个Textarea文本框中,这样就不会去请求路径。

    jQuery插件代码:

    //包装延迟加载容器 
    $.fn.wraplazyload = function(value) { 
        
    this.html('<textarea class="text-lazyload">' + value + '</textarea>'); 
    };

    其中将text-lazyload的display设置为none,让它不显示。

    接着,我需要开始“解放”图片了

    jQuery插件代码:

    var content = $('<div>' + $(this).val().replace (/src=/gi, 'dynamic='+ '</div>'); 
    $(
    this).after(content);

    这里的this指的是刚才包装的textarea,这里首先把Html内容 的包含“src=”的文本替换为“dynamic=” (注:这里简单进行 这样的替换,如果一般性的考虑的话),

    然后创建一个jQuery对象,在textarea后面追加这样的一个DOM 节点。利用dynamic的替代属性,就防止了图片的加载。

    3. 该jQuery插件不尽支持对于Img图片的延迟加载,对于任何 一个DOM节点都可以进行延迟加载。

    jQuery插件代码:

    element.each(function() { $(this).css('visibility''hidden'); }); 

    element为一系列DOM元素或者Img标签,注意这里要使用 visibility:hidden,这样才能保持DOM元素或者Img标签的高度,display:none,会将元素的高度置0.

    4. 然后,开始编写滚动条触发事件代码:

    jQuery插件代码:

    代码
    $(settings.container).bind(settings.event, function(event) { 

        
    var pixel = 0;
        
    if (settings.position == 'vertical') {
            pixel 
    = $(settings.container).height() + $(settings.container).scrollTop();
        }
        
    else if (settings.position == 'horizontal') {
            pixel 
    = $(settings.container).width() + $(settings.container).scrollLeft();
        } 

        element.each(
    function() {
            
    if ($(this).css('visibility'!= 'visible' &&
                (settings.position 
    == 'vertical' && pixel >= $(this).offset().top
                    
    || settings.position == 'horizontal' && pixel >= $(this).offset().left)) { 

                $(
    this).css('visibility''visible'); 

                
    if (settings.effect == 'fadeIn') {
                    $(
    this).hide();
                    $(
    this)[settings.effect](settings.effectTime);
                }
                
    if (settings.loadType == 'item')
                    $(
    this).html($(this).html().replace(/dynamic=/gi, 'src='));
                
    else if (settings.loadType == 'image')
                    $(
    this).attr('src', $(this).attr('dynamic')).removeAttr('dynamic');
            }
        });
    });

    当滚动条将图片或者DOM节点给展示出来的时候,会调用$(this).css('visibility', 'visible'); 

    并且如果是加载图片,将调用$(this).attr('src', $(this).attr('dynamic')).removeAttr('dynamic');

    如果是加载Dom节点,将调用$(this).html($(this).html ().replace(/dynamic=/gi, 'src='));

    思路是将dynamic转换为src,得以进行Http请求。

    5. 最后看代码如何应用该插件:

    前端JS代码:

    代码
    var html = '';
    html 
    += '<div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151653.jpg" width="600" height="500" /><br/><img src="http://img9.zol.com.cn/desk_pic/big_413/412107.jpg" width="600" height="500" /></div>';
    html 
    += '<div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151656.jpg" width="600" height="500" /></div>';
    html 
    += '<div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_413/412108.jpg" width="600" height="500" /></div>';
    html 
    += '<div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_419/418139.jpg" width="600" height="500" /></div>';
    html 
    += '<div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151647.jpg" width="600" height="500" /></div>';
    $(
    '#container2').wraplazyload(html);
    $(
    '#container2').datalazyload({ loadType: 'image', effect: 'fadeIn'/*, position: 'horizontal'*/ }); 

    Html代码:

    <div id="container2"> 
    </div>

    首先对于container2节点进行包装,然后调用datalazyload方 法,这里loadType加载类型为加载图片“image”,也可以设置为 加载DOM节点“item”,effect为加载效果,position可以设置为 水平加载还是垂直加载,Options参数完整为:

    jQuery插件代码:

    代码
    var settings = {
        dataContainer: 
    '.text-lazyload',
        dataItem: 
    '.item-lazyload',
        loadType: 
    'item',                   //可以为item(条目加载),img(图片加载)
        container: window,                  //滚动的容器
        event: 'scroll',
        effect: 
    'normal',                   //效果类型
        effectTime: 1000,                   //效果持续时间
        position: 'vertical'                //可以为vertical(垂直加载),horizontal(水平加载)
    };

    这些参数都是可设置的,这里不在过多介绍,具体可以查看源代码。

    6. 最后,插件只有在滚动条拉到DOM节点或者图片的可视区域的时候,才进行加载,达到了数据延迟加载的效果。该插件已经成功应用到项目中去了.

    数据延迟加载JQuery插件的演示地址:http://aspspider.info/sunleepy/lazyload.html

    源代码下载

  • 相关阅读:
    621
    Java里的日期和时间学习
    [置顶] 宏扩展和参数扫描
    android 按字母搜索
    使用Eclipse EE开发web项目
    免解压版的Mysql的启动脚本,并且执行导入(windows)
    高焕堂《android从程序员到架构师之路》 YY讲坛直面大师学习架构设计
    Android 计时与倒计时
    poj 1564 Sum It Up | zoj 1711 | hdu 1548 (dfs + 剪枝 or 判重)
    字符型驱动程序的结构框架
  • 原文地址:https://www.cnblogs.com/liping13599168/p/1736620.html
Copyright © 2020-2023  润新知