javascript設計模式實踐之模板方法--具有百葉窗切換圖片效果的JQuery插件(二)

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

在上一篇《javascript設計模式實踐之迭代器--具有百葉窗切換圖片效果的JQuery插件(一)》里,通過採用迭代器模式完成了各初始化函數的定義和調用。 接下來就要完成各個切換效果的編寫。 先思考一下一個切換效果需要完成的操作 1.準備階段,將各個strip歸位到動畫效果開始的位置。 2.動畫效


在上一篇《javascript設計模式實踐之迭代器--具有百葉窗切換圖片效果的JQuery插件(一)》里,通過採用迭代器模式完成了各初始化函數的定義和調用。

接下來就要完成各個切換效果的編寫。

先思考一下一個切換效果需要完成的操作

1.準備階段,將各個strip歸位到動畫效果開始的位置。

2.動畫效果處理。

3.執行。

3.完成。

所有的切換效果都具備上述3步操作。

既然這樣就好抽象了。

可以對上述的操作進行單獨定義,然後通過模板方法模式對各個操作進行調用。

所謂的模板方法模式,其實就是有這麼一個方法完成一個業務流程的處理,在這個業務流程中的某些個細節則交個子對象去處理。就好比組裝汽車的流水線就是一個模板,它規定了組裝的流程,但是工人是跳著裝,還是走著裝,還是拿個設備輔助著裝那就是安裝者的事兒了。

 

按照模板方法模式編寫一個基本效果對象。

    var baseEffect = {
        prepare: function (context) {
            throw new Error('請重寫prepare方法');
        },
        transform: function (context) {
            throw new Error('請重寫transform方法');
        },
        execute: function (context) {
            this.prepare(context);
            return this.transform(context);
        }
    };

prepare函數:準備階段操作。

transform函數:動畫效果處理。

這兩個方法其實就是各個切換效果根據自身的效果特性需要完成的細節。

execute函數就是執行操作,也是模板方法,在其中完成了對準備階段和動畫處理的流程調用,當然是先準備後進行動畫效果處理流程。

按照約定,transform方法必須返回一個jquery的promise對象用來控制動畫完成向外部的通知。

關於promise的使用可參考《jquery的promise實踐--連續載入圖片》。

 

基本效果對象完成後,接下編寫各個實際的效果對象,並從基本效果繼承,完成準備操作和動畫處理的編寫。

先編寫從下往上移動各窗帘條strip的效果

    var downToUpEffect = (function (baseEffect) {
        var effect = jquery.extend({}, baseEffect);
        var imgSrc;

        effect.prepare = function (context) {
            imgSrc = context.nextImgSrc();
            for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
                $strip.css('background-image', 'url(' + imgSrc + ')');
                $strip.css('top', context.stripHeight + 'px');
            }
        };

        effect.transform = function (context) {
            var dfd = jquery.Deferred();
            for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
                if (i == context.$strips.length - 1) {
                    $strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement, function () {
                        context.$container.css('background-image', 'url(' + imgSrc + ')');
                        dfd.resolve();
                    });
                } else {
                    $strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement);
                }
            }

            return dfd.promise();
        };

        return effect;
    })(baseEffect);

可以看到,一上來,用了jquery.extend函數完成從基本效果對象的繼承,書上基本都是在用構造器和原型繼承的方式實現繼承,但是本質上,在javascript的世界里函數是一等公民,對象實際上就是鍵值對的集合,沒必要生搬硬套OOP的一套東西,這裡用了jquery的繼承方法,實際上就是將一個對象的方法複製過來生成另一個對象。

downToUpEffect對象只需關心在準備階段,將所有的窗帘條strip的top都設到容器的下邊沿處,在動畫處理階段通過jquery.animate動畫方法對各個窗帘條strip的top執行從容器的下沿到上沿的動畫。

每個strip的動畫都會基於一個簡單的計算得出有不同的延遲,這樣在視覺上會產生strip是階梯式的往上移動。

transform函數內通過jquery.deffered對象的resolve方法完成最後一個動畫執行完成的通知。並且transform方法將promise返回使得上層可以對動畫的完成進行吃處理。

 

再比如從上往下的效果對象編寫

    var upToDownEffect = (function (baseEffect) {
        var effect = jquery.extend({}, baseEffect);
        var imgSrc;

        effect.prepare = function (context) {
            imgSrc = context.nextImgSrc();
            for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
                $strip.css('background-image', 'url(' + imgSrc + ')');
                $strip.css('top', '-' + context.stripHeight + 'px');
            }
        };

        effect.transform = function (context) {
            var dfd = jquery.Deferred();
            for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
                if (i == context.$strips.length - 1) {
                    $strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement, function () {
                        context.$container.css('background-image', 'url(' + imgSrc + ')');
                        dfd.resolve();
                    });
                } else {
                    $strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement);
                }
            }

            return dfd.promise();
        };

        return effect;
    })(baseEffect);

從上面的代碼看下來,他們的結構是一致的,不同的就是準備階段和動畫處理的細節不同。

upToDownEffect的準備階段負責把所有窗帘條strip的下沿對準容器的上沿,也就是移動容器的外面去。動畫處理階段就是把strip從上面移下來,並通過延遲造成階梯式往下移動的效果。

 

其他的效果對象也是在這樣的結構下完成屬於效果自身的功能編碼。

採用模板方法模式可以使得各個具體的效果對象中的編碼只關心屬於自己的東西,結構較為清晰,關註重點突出自身的業務邏輯,想到新效果只要專註新效果的實現即可。

其他效果對象的編寫可參考全部代碼。

 

下一篇繼續:《javascript設計模式實踐之職責鏈--具有百葉窗切換圖片效果的JQuery插件(三)

代碼:


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

-Advertisement-
Play Games
更多相關文章
  • "Gist Link" 看完我想撞牆,為什麼早沒想到。。。
  • 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插件(二)》里,通過採用模板方法模式完成了切換效果對象的構建編寫。 接下來就是完成各效果對象的調用和聯動。 切換要求:當前圖片顯示指定時間後執行切換效果並切換下一張圖片,最後一個切換後從頭開始。 按照要求一個
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...