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插件(二)

代码:

时间: 2024-10-15 01:17:50

javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)的相关文章

javascript设计模式实践之职责链--具有百叶窗切换图片效果的JQuery插件(三)

在上一篇<javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)>里,通过采用模板方法模式完成了切换效果对象的构建编写. 接下来就是完成各效果对象的调用和联动. 切换要求:当前图片显示指定时间后执行切换效果并切换下一张图片,最后一个切换后从头开始. 按照要求一个效果对象完成后要执行下一个,最后一个完成后要从头开始, 看上去就是一个带状态通知的环形列表,类似于这样的特征,可以采用职责链模式来构建. 职责链就是由不同的功能处理构成的链表,每一个功能处理作为一个

javascript设计模式学习之七——迭代器模式

一.迭代器模式定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,并且不需要暴露该对象的内部表示. 在当前大部分语言中,都已经内置了迭代器模式.迭代器有内部迭代器和外部迭代器之分,一般现有语言中实现的大多是内部迭代器. 二.jquery中的each实现 //类似jquery中的each迭代器 $.each=function(obj,callback){ var value, i=0, isArray=isArrayLike(obj), length=obj.length; if(isA

javascript - 简单实现一个图片延迟加载的jQuery插件

最近在看一本书<Third-Party Javascript>很不错,推荐给大家,下载地址各位自己搜索了. 步骤: 1.打开google,鉴于google基本打不开,那么就打开这个网址吧.http://www.aol.com 2.搜索third party javascript filetype:pdf 一般都可以下载到电子书了.目前只有英文版. 这书中有一章讲到了提高app的效率,其中有一点就是延迟加载初始化不需要的资源,结合书中给出的部分代码,我这里简单的弄了一个jQuery的插件. 首先

Html5添加三联切换仿3D效果旋转木马jQuery插件教程

一.使用方法 <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/gallery.js"></script> 二.Html结构 <div id="wrapper"> <div id=&quo

用CALayer实现淡入淡出的切换图片效果

由于直接更改layer的contents显示的隐式动画切换的时候的动画持续时间没办法控制, 切换效果不尽人意,所以这里配合了CABasicAnimation实现淡入淡出的切换效果, 另外还可以使用组合动画对多种动画进行组合, 实现更复杂的动画效果, 这里仅仅只是多添加了缩放效果为示例... 效果图: github:https://github.com/RinpeChen/changeImageWithAnimationByCALayer.git

JS实现动态瀑布流及放大切换图片效果(js案例)

整理了一下当时学js写的一些案例,再次体验了一把用原生JS实现动态瀑布流效果的乐趣,现在把它整理出来,需要的小伙伴可以参考一下. 该案例主要是用HTML+CSS控制样式,通过JS实现全局瀑布流以及点击图片放大.上下切换效果.HTML布局写的很简单,图片加载主要是在JS中通过访问自定义的JSON字符串来实现.动态瀑布流的原理简单理解就是把新需要加载的图片放在上一排总高度最小的图片或模块下面,实现参差不齐的多栏布局效果.具体效果如下: 做这个案例我用了之前自己封装的框架,所以小伙伴需要到我的另一篇文

ImageButton单击切换图片效果

转载请标明: http://blog.csdn.net/u012637501 我们平时在使用手机app时,常常会发现当我们按下某个按钮时相应按钮会发生变化,当我们松手时又恢复了原来的样子.或是,当你连续单击同一个按钮,会实现不同的功能.刚开始的时候感觉很神奇,那么现在我们来揭开她的面纱,经过下面的学习我相信你也可以轻轻松松将其拿下! 一.单击效果 首先看下将要实现的效果: Android为实现图片按钮按下的效果有两种方式可以实现:一是增加代码,二配置XML. 1.方式一:增加代码实现 (1)ma

【转】Android android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)

首先我们还是看一些示例:(网易,新浪,百度)      下面我简单的介绍下实现方法:其实就是listview addHeaderView.只不过这个view是一个可以切换图片的view,至于这个view怎么做,就要根据自己的喜爱了,实现有多种方法,下面我简单介绍一下. 第一种:ViewFlipper+GestureDetector 主布局就是一个listview,这里就不介绍了,我介绍下切换图片布局head_iamge.xml 1 <span style="font-size:12px;&

android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)

首先我们还是看一些示例:(网易,新浪,百度) 显示效果都不错,可是手感就不一样了,百度最棒,网易还行,新浪就操作很不好,这里我说的是滑动切换图片.自己可以测试一下.不得不说牛叉的公司确实有哦牛叉的道理. 下面我简单的介绍下实现方法:其实就是listview addHeaderView.只不过这个view是一个可以切换图片的view,至于这个view怎么做,就要根据自己的喜爱了,实现有多种方法,下面我简单介绍一下. 第一种:ViewFlipper+GestureDetector 主布局就是一个li