zoukankan      html  css  js  c++  java
  • javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)

    类似于幻灯片的切换效果,有时需要在网页中完成一些图片的自动切换效果,比如广告,宣传,产品介绍之类的,那么单纯的切就没意思了,需要在切换的时候通过一些效果使得切换生动些。

    比较常用之一的就是窗帘切换了。

    先贴上完成的效果。

    实现原理不复杂,在动的一条一条的称之为“窗帘条”或者是“strip”,每一个strip都是一个div,类似于雪碧图的方式将其背景图的位置设置为strip的可视位置,然后用jquery的animate让他们按照一定规律动起来就完成窗帘切换效果了。

    为了使用方便,将这个功能作为jquery的插件方式进行编写。

    插件名:bobenut.curtain.jquery.js

    (function (jquery) {
        jquery.fn.curtain = function (options) {
            //TODO
    
        }
    })(jQuery);

    调用页面

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <style>
                #curtain {
                    width: 800px;
                    height: 600px;
                    position: relative;
                    overflow: hidden;
                    margin:0 auto;
                }
            </style>
        </head>
        <body>
            <div id="curtain" >
                <img src="1.jpg"/>
                <img src="2.jpg"/>
                <img src="3.jpg"/>
                <img src="4.jpg"/>
            </div>
    
            <script type='text/javascript' src="jquery-1.11.3.min.js"></script>
            <script type='text/javascript' src="../src/bobenut.curtain.jquery.js"></script>
            <script type='text/javascript'>
                $('#curtain').curtain();
            </script>
        </body>
    </html>

    通过JQuery选择了包含图片的div后直接调用即可。

    $('#curtain').curtain();

    框架写完了,接下去进入初始化环节。

    初始化包括:初始化尺寸、动画容器、被切换的图片,各个窗帘条的生成,默认背景,切换时用到的时间参数。

    这些个初始化操作写在一个函数里显然会比较庞大,而且未来需要增加的功能都要动这么一个函数,显然不明智,那么就把他们按照初始化的职能进行拆分。

    那么这么多初始化函数的调用就成了问题,难道要硬写每个函数进行独立调用?显然这种方式是很low的。

    像这样每个函数都是具备相同的输入参数,都没有返回结果,那么可以说是相同形态的,可以采用迭代器设计模式进行调用。

    所谓的迭代器就是顺序访问各元素,并且不用关心各元素的细节,其实就是循环访问,对于这些个初始化函数的调用我们就可以采用迭代器模式进行调用,下面各函数定义完后进行迭代器模式的调用。

    初始化的结果肯定要找地方放,作为基本的环境上下文context供给后面的切换使用。

    在本插件模块中定义个模块级的变量context。

    所有初始化的结果都保存在context中。

    var context = {};

    接下来是各个初始化操作函数

    1)初始化容器

        function initContainer(options) {
            context.$container = options.$container;
        }

    容器就是包含一组图片的div,options是调用时传递进来的参数,因为这里的container是用jquery选择来的,所以加个$以示区分。

    2)初始化尺寸

        function initSize(options) {
            context.stripCount = options.stripCount;
            context.containerWidth = options.width.replace('px', '');
            context.containerHeight = options.height.replace('px', '');
            context.stripWidth = context.containerWidth / context.stripCount;
            context.stripHeight = context.containerHeight;
        }

     获取容器的大小,计算strip的大小。

    3)初始化容器内的所有图片

        function initImgs(options) {
            context.imgSrcs = [];
            context.$container.children().each(function (index, element) {
                var $element = $(element);
                $element.css('display', 'none');
                context.imgSrcs.push($element.attr('src'));
            });
    
            context._imgCurrentIndex = 0;
            context.nextImgSrc = function () {
                if (++context._imgCurrentIndex > context.imgSrcs.length - 1) {
                    context._imgCurrentIndex = 0;
                }
    
                return context.imgSrcs[context._imgCurrentIndex];
            };
        }

    一上来了把需要切换的图片全部隐藏,并把他们的url保存在数组中以便于切换时使用。

    提供一个获取下一张图片url的方法,使得在切换时能方便获取下一张图片的url。

    4)初始化strip

        function initStrips(options) {
            context.$strips = [];
            for (var i = 0; i < context.stripCount; i++) {
                var $strip = jquery('<div></div>');
                $strip.css('background-size', context.containerWidth + 'px ' + context.containerHeight + 'px');
                $strip.css('background-position-x', i * context.stripWidth * -1 + 'px');
                $strip.css('background-position-y', '0px');
                $strip.css('background-repeat', 'no-repeat');
                $strip.css('position', 'absolute');
                $strip.css('left', (i * context.stripWidth) + 'px');
                $strip.css('top', context.stripHeight + 'px');
                $strip.css('width', context.stripWidth + 'px');
                $strip.css('height', context.stripHeight + 'px');
                $strip.css('display', 'block');
                $strip.css('overflow', 'hidden');
                $strip.css('zoom', '1');
                context.$strips.push($strip);
                context.$container.append($strip);
            }
        }

    生成所有的strip,给她们设置默认的大小,将要切换的图设成背景图,通过background-position-x和y调整背景图的显示位置,然后将strip保存于数组中便于使用。

    5)初始化默认背景

        function initDefaultBackground() {
            context.$container.css('background-image', 'url(' + context.imgSrcs[0] + ')');
            context.$container.css('background-size', context.containerWidth + 'px ' + context.containerHeight + 'px');
        }

    默认将第一张图片作为容器的背景。

    6)初始化切换时间参数

        function initTime(options) {
            context.interval = options.interval;
            context.baseDelay = options.baseDelay;
            context.delayIncrement = options.delayIncrement;
        }

    设置前后图片的切换标准间隔时间interval,切换时每个strip的切换延迟时间和延迟增量时间。

    各个初始化函数完成,接下来采用迭代器模式对各个初始化函数进行调用。

        function init(options) {
            var initFuncs = [initContainer, initSize, initImgs, initStrips, initDefaultBackground, initTime];
            for (var i = 0, f; f = initFuncs[i++];) {
                f(options);
            }
        }

    在这里,按照各初始化函数的优先级,把他们放到一个数组中,通过循环这个数组,对每一个函数进行调用,好处就是,新加一个初始化函数的时候,只需往数组的末尾添加即可,甚至可以把初始化函数数组定义到外部,这样,init函数就符合开闭原则了。

    jquery有一种更高大上的迭代处理方法就是each,那么就对init函数略加修改。

        function init(options) {
            var initFuncs = [initContainer, initSize, initImgs, initStrips, initDefaultBackground, initTime];
            jquery.each(initFuncs,function(i,f){
                f(options);
            });
        }

    each函数的第一个参数是被迭代的对象或数组,第二个参数是迭代每一个元素时的处理回调函数,好处就是,循环的事您就别管了,只关心处理。

    至此,初始化函数的定义完成。

    为了完成init函数的调用,需要考虑生成默认的options,因为外部可以不传递任何参数。

    然后完成对init函数的调用。

        function setDefaultOptions(options, $container) {
            options = options || {};
            options.$container = $container;
            options.width = options.width || '800px';
            options.height = options.height || '600px';
            options.stripCount = options.stripCount || 10;
            options.interval = options.interval || 2;
            options.baseDelay = options.baseDelay || 400;
            options.delayIncrement = options.delayIncrement || 80;
    
            return options;
        }
    
        jquery.fn.curtain = function (options) {
    
            init(setDefaultOptions(options, this));
    
    }

    通过setDefaultOptions函数负责确保各个必须的参数都有默认值。

    然后将规整过的options作为init的输入,对init函数进行调用。

    至此,通过迭代器的设计模式完成了各个初始化函数的定义和调用。

    下一篇继续:《javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)

    代码:

  • 相关阅读:
    备战noip week1
    20200820校测
    UVA 11419 SAM I AM
    需求沟通技巧
    ReentrantLock和ReentrantReadWriteLock对比
    线程池浅析
    常用设计模式之单例模式
    java开发3~5年工作经验面试题
    2019计划
    Linux系统安装Tomcat
  • 原文地址:https://www.cnblogs.com/kongxianghai/p/5161420.html
Copyright © 2011-2022 走看看