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

代碼:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM