javascript設計模式實踐之迭代器--具有百葉窗切換圖片效果的JQuery插件(一)

来源:http://www.cnblogs.com/kongxianghai/archive/2016/01/29/5161420.html
-Advertisement-
Play Games

類似於幻燈片的切換效果,有時需要在網頁中完成一些圖片的自動切換效果,比如廣告,宣傳,產品介紹之類的,那麼單純的切就沒意思了,需要在切換的時候通過一些效果使得切換生動些。 比較常用之一的就是窗帘切換了。 先貼上完成的效果。 實現原理不複雜,在動的一條一條的稱之為“窗帘條”或者是“strip”,每一個s


類似於幻燈片的切換效果,有時需要在網頁中完成一些圖片的自動切換效果,比如廣告,宣傳,產品介紹之類的,那麼單純的切就沒意思了,需要在切換的時候通過一些效果使得切換生動些。

比較常用之一的就是窗帘切換了。

先貼上完成的效果。

 

 

 

實現原理不複雜,在動的一條一條的稱之為“窗帘條”或者是“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插件(二)

代碼:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Github 地址 項目背景 最近做個項目,需要進行試駕分析,所謂“試駕”,是指顧客在 4S 店指定人員的陪同下,沿著指定的路線駕駛車輛,從而瞭解這款汽車的行駛性能和操控性能。通常,無論是車廠(製造商),還是4S店(經銷商),對車輛的試駕都比較感興趣。從車廠的角度,不僅僅可以知道某輛車是否受歡迎,還...
  • 1.記憶體分區: 高(記憶體地址大) 棧底 棧區 堆區 靜態區 常量區 低(記憶體地址小) 代碼區 2.棧:數據結構 (1)特點:先進後出 (2)操作:入棧(push)出棧(pop) (3)棧從高->低分配空間 char a = 0; char b = 0; char c = 0; printf(“a:%
  • 在文章《Python開發、調試、爬蟲類工具大全》裡面向大家總結了各種實用工具和爬蟲技術,今天小編收集了5篇帶有實例乾貨的資料,趕緊來看看吧!另外,喜歡寫博客的博主可以申請加工程師博主交流群:391519124,分享你的博文,和大牛們一起交流技術~ 一、OSINT + Python = 自定義黑客Py
  • 說到外觀模式,很容易想到的是設計一件漂亮的衣服然後穿上自己的身上,讓自己看起來更加的漂亮,但是這個可能並不是這樣子的,從更深層次的來說,外觀更應該是所見即所得的,對於觀眾來說,看起來可能就是很簡單,但是裡面所有的東西的複雜程度,我們並不知道。 在程式開發的過程中,我們時常的會用到一些類與類之間的關聯
  • 回到目錄 閑話多說 領域事件大叔感覺是最不好講的一篇文章,所以拖欠了很久,但最終還是在2015年年前(陰曆)把這個知識點講一下,事件這個東西早在C#1.0時代就有了,那時學起來也是一個費勁,什麼是委托,哪個是事件,搞的大家是糊裡糊塗,進入C#2.0時代後,大叔也買了一本書,對於delegate和ev
  • 引言 說實話,我看過GoF《Design Patterns》,也曾深深的被李建忠《設計模式》系列Webcast吸引。但是還沒有見過“Double Dispatch模式”。的確GoF提及的設計模式只是最初對設計模式的系統介紹,它不可能涵蓋所有的模式。另外隨著時間的流逝,技術日新月異的變化,技術大牛們又
  • 在上一篇《javascript設計模式實踐之模板方法--具有百葉窗切換圖片效果的JQuery插件(二)》里,通過採用模板方法模式完成了切換效果對象的構建編寫。 接下來就是完成各效果對象的調用和聯動。 切換要求:當前圖片顯示指定時間後執行切換效果並切換下一張圖片,最後一個切換後從頭開始。 按照要求一個
  • 在上一篇《javascript設計模式實踐之迭代器--具有百葉窗切換圖片效果的JQuery插件(一)》里,通過採用迭代器模式完成了各初始化函數的定義和調用。 接下來就要完成各個切換效果的編寫。 先思考一下一個切換效果需要完成的操作 1.準備階段,將各個strip歸位到動畫效果開始的位置。 2.動畫效
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...