zoukankan      html  css  js  c++  java
  • jQuery.imgLazyLoad图片懒加载组件

    一、前言

    当一个页面中请求的图片过多,而且图片太大,页面访问的速度是非常慢的,对用户的体验非常不友好;使用图片懒加载,可以减轻服务器的压力,增加页面的访问量,这里主要是总结一下我自己写的图片懒加载组件jQuery.imgLazyLoad;使用该组件应在img标签中设置一个imglazyload-src属性,存放图片地址。

    二、应用实例demo

    复制代码
    /**
     * component: imgLazyLoad 2013/12/12 华子yjh
     * invoking: jQuery.imgLazyLoad(options)
     *
        // 配置对象
        options = {
            container: 'body',              // 外围容器,默认body
            tabItemSelector: '',            // Tab切换面板选择器
            carouselItemSelector: '',       // 图片轮播面板选择器
            attrName: 'imglazyload-src'     // 图片地址属性
            diff: 300                       // 预加载像素
        }
     *
     */
    复制代码

    图片轮播懒加载:http://miiee.taobao.com
    Tab切换图片懒加载:http://miiee.taobao.com/main.htm
    浏览器滚动图片懒加载:http://miiee.taobao.com/themes/theme_151.htm

    三、设计思路

    1、处理浏览器下拉滚动

    比较 $(window).scrollTop + $(window).height() 与 img.offset().top 的值,当图片在浏览器窗口中,开始加载图片

    2、处理Tab切换 与 图片轮播

    在处理Tab切换 与 图片轮播,组件提供了一个用于事件处理的函数 handleImgLoad,参数idx:

    该参数对于图片轮播,是作为下一轮轮播面板的索引,将下一轮轮播面板中的所有图片预加载
    对于Tab切换,则是作为tab项的索引,加载当前显示tab项中的所有图片

    3、选择器处理

    3.1、滚动下拉选择器的处理

    在 配置对象中有一个attrName,是保持图片地址的一个属性 选择器为:img[config.attrName];

    其次图片是显示的,如果隐藏,则不加载图片, 选择器为:img[config.attrName]:visible;

    再次如果图片已加载,为其加上一个img-loaded的className,为了过滤已加载过的图片,选择器为:img[config.attrName]:visible:not(.img-loaded);

    最后如果一个页面使用多次组件,第一次使用时,当配置对象container为body子元素,第二次应该过滤前一次container匹配元素中的图片,
    依次类推,选择器为:img[config.attrName]:visible:not(.img-loaded):not(jQuery.imgLazyLoad.selectorCache)

    3.2、Tab切换、图片轮播选择器的处理

    在 配置对象中有tabItemSelector 或 carouselItemSelector ,结合事件处理函数的参数idx,获取当前Tab项或下一轮轮播面板中的图片
    选择器为:tabItemSelector:eq(idx) img 或 carouselItemSelector:eq(idx) img

    如果idx === undefined,选择器为:tabItemSelector:visible img 或 carouselItemSelector:eq(0) img
    我是根据我自己写的jQuery组件自行判断的 

    四、组件源码

    复制代码
    $.extend({
        imgLazyLoad: function(options) {
            var config = {
                    container: 'body',
                    tabItemSelector: '',
                    carouselItemSelector: '',
                    attrName: 'imglazyload-src',
                    diff: 0
                };
            $.extend( config, options || {} );
    
            var $container = $(config.container),
                offsetObj = $container.offset(),
                compareH = $(window).height() + $(window).scrollTop(),
    
                // 判断容器是否为body子元素
                bl = $.contains( document.body, $container.get(0) ),
    
                // 过滤缓存容器中的图片
                notImgSelector = jQuery.imgLazyLoad.selectorCache ? ':not(' + jQuery.imgLazyLoad.selectorCache + ')' : '',
                imgSelector = 'img[' + config.attrName + ']:visible' + notImgSelector,
                $filterImgs = $container.find(imgSelector),
    
                // 用于阻止事件处理
                isStopEventHandle = false,
                
                // 是否自动懒加载,为true时,绑定滚动事件
                isAutoLazyload = false;
    
            // 缓存容器为body子元素的图片选择器
            jQuery.imgLazyLoad.selectorCache = bl ? (jQuery.imgLazyLoad.selectorCache ? (jQuery.imgLazyLoad.selectorCache + ',' + config.container + ' img') : config.container + ' img') : jQuery.imgLazyLoad.selectorCache;
    
            function handleImgLoad(idx) {
                if (isStopEventHandle) {
                    return;
                }
                /**
                 处理Tab切换,图片轮播,在处理$filterImgs时,没有过滤img:not(.img-loaded),因为只是在一个面板中,
                 还有其他面板,如果再次触发,可能$filterImgs.length为0,因此只能在外围容器中判断过滤图片length
                */            
                if ($container.find('img:not(.img-loaded)').length === 0) {
                    isStopEventHandle = true;
                }
    
                var itemSelector = config.tabItemSelector || config.carouselItemSelector || '';
                if (itemSelector) {
                    if (typeof idx !== undefined && idx >= 0) {
                        $filterImgs = $container.find(itemSelector).eq(idx).find('img');
                    }
                    else {
                        if (itemSelector === config.carouselItemSelector) {
                            $filterImgs = $container.find(itemSelector).eq(0).find('img');
                        }
                        else {
                            $filterImgs = $container.find(itemSelector + ':visible').find('img');
                        }
                    }
                }
                else {
                    $filterImgs = $filterImgs.not('.img-loaded'); // 自动懒加载,过滤已加载的图片
                    isAutoLazyload = true;
                }
    
                // 当外围容器位置发生变化,需更新
                offsetObj = $container.offset();
    
                if ($filterImgs.length > 0) {
                    $filterImgs.each(function(idx, elem) {
                        var $target = $(elem),
                            targetTop = $target.offset().top,
                            viewH = $(window).height() + $(window).scrollTop() + config.diff;
    
                        if (bl) {
                            $target.attr('src', $target.attr(config.attrName)).removeAttr(config.attrName).addClass('img-loaded');
                        }
                        // 内容在视窗中
                        if (viewH > targetTop) {
                            $target.attr('src', $target.attr(config.attrName)).removeAttr(config.attrName).addClass('img-loaded');
                        }
                    });
                }
                else {
                    // 处理滚动事件
                    isStopEventHandle = true;
                    $(window).unbind('resize scroll', handleImgLoad);
                }
            }
    
            handleImgLoad();
            if (isAutoLazyload) {
                $(window).bind('resize scroll', handleImgLoad);
            }
    
            // 提供事件处理函数
            return {
                handleImgLoad: handleImgLoad
            }
        }
    });
    
    // 保存非body子元素容器下的图片选择器
    jQuery.imgLazyLoad.selectorCache = '';
    复制代码

    五、实例应用代码

    复制代码
    // 轮播图片 懒加载
    (function(){
        var imgLazyLoadObj = $.imgLazyLoad({
            container: '#first-block-switch',
            carouselItemSelector: '.switch-content li'
        });
        $.switchable({
            wrapSelector: '#first-block-switch',
            contentSelector: '.switch-content',
            prevBtnSelector: '.prev',
            nextBtnSelector: '.next',
            triggerSelector: '.switch-nav',
            autoPlay: true,
            duration: 300,
            interval: 3000,
            handleImgLoad: imgLazyLoadObj.handleImgLoad
        });
    }());
    
    // 浏览器滚动 懒加载
    $.imgLazyLoad({ diff: 300 });
    复制代码
  • 相关阅读:
    MSP430程序库<二>UART异步串口
    MSP430程序库<五>SPI同步串行通信
    MSP430程序库<四>printf和scanf函数移植
    短信猫的实现(C#)类库开源啦
    短信猫软件的实现(C#)<十三>超长短信
    Linq to SQlite的使用
    MSP430程序库<三>12864液晶程序库
    查看Linux中自带的jdk ,设置JAVA_HOME
    [linux] vimrc
    [C#] socket demo
  • 原文地址:https://www.cnblogs.com/amylis_chen/p/4470051.html
Copyright © 2011-2022 走看看