使用單體模式設計原生js插件


----------基於上次寫的jquery插件進行改造  http://www.cnblogs.com/GerryOfZhong/p/5533773.html

 

背景:jQuery插件依賴jQuery庫,雖然jQuery使用十分廣泛,但是對於移動開發或者在其他帶寬需求需要注意的時候,就得考慮,因為我不可能完成一項技術相對來說引用了一個更大的庫,這樣之不值得的。所以原生js是所有瀏覽器都支持的一種語言,原生js相對來說就very good了,但是原生js相對新手或者沒有很強基礎的人來說還是相對比較深奧晦澀一點的,畢竟要考慮一些額外的因素:

  • 不能污染全局的變量,因為你不知道你的代碼將會和其他庫或者頁面加載的廣告代碼進行沖突
  • 一些高階的設計模式,因為一些設計模式都是十分經典的思想的凝結,用語言實現也相對比較復雜
  • 前端面向對象編程,因為js自由度比較高,沒有和后台定義一樣。比如模擬的接口,繼承,封裝等,來實現功能強大的架構或者需求
  • ..........

 

設計模式單體模式

好處:在使用單體模式的時候,你會享受到真正的私有成員帶來的所有好處,而不必付出什么代價,因為單體淚只會被實例化一次單體模式之所以是javascript中最流行的、應用最廣泛的模式之一

    • 描述性命名增強代碼的自我說明性
    • 包裹單體中可以防止被其他人誤改
    • 與第三方庫和廣告隔離起來
    • 后期進行優化,比如惰性加載

弊端:在使用單體模式的時候,必須要十分了解閉包等概念,而且以后結合其他設計模式共同使用的時候,復雜度和代碼量相對來說要求更高,所以需要使用者自己進行衡量,值不值得使用,會不會增加項目開發難度等。如果值得就用,不值得就不建議使用

 

下面為閉包單體模式的骨架(用空專門講設計模式和一些案例和使用):

var nameSpance= window.nameSpance|| {};  //聲明一個空間

nameSpance.gerry=(function(){
    //這里可以存放私有屬性和私有方法,不對外開放,防止其他開發者私自改動
    var privateAttr = false;

    function privateMethod (){
        console.log("這是私有方法,不對外開放...");
    }

    //這里為拋出對象,供開發者使用的
    var publicObject = {
        publicAttr : true,
        publicMethod : function(){
            console.log("這是拋出方法,供開發者使用...")
        }
    }

    return publicObject;
})()    

 

原生代碼設計:

  1. 聲明空間然后搭建骨架
    var gerry = window.gerry || {};  //聲明
    gerry.setBackgroundImage = (function(){

      var
    publicMethods = {};
        return publicMethods; 
    })()

     

  2. 設置插件默認值(注明:該默認值不提供外部修改,不開放特權方法去set改變它的值)
    var gerry = window.gerry || {};  //聲明
    gerry.setBackgroundImage = (function(){
            //私有參數設置(不對外開放)
             var config={
                imgArr: [],        //圖片數組
                imgSecond: 1000,  //圖片淡出的時間
                isRandom:false    //是否為隨機圖片
            }
    
            //暴露給開發者使用的方法,可隨意拓展
            var publicMethods = {};
            return publicMethods ;
    })()

     

  3. 封裝一些tool,放在私有方法中,因為畢竟不是jQuery了,一些方法需要自己進行封裝下
    var tool = {
                //ID選擇器
                id_selector:function (selector){
                    return document.getElementById(selector);
                },
                //創建節點
                createElement:function(node){
                    return document.createElement(node);
                },
                //設置節點屬性
                attr:function(setArrObject){
                    for(var i = 0,len=setArrObject.attribute.length;i<len;i++){
                            setArrObject.node.setAttribute(setArrObject.attribute[i].key,setArrObject.attribute[i].value);
                    }
                }
            }

     

  4. 設置一些需要使用的樣式,放到一個css對象中
            //設置的樣式
            var css = {
                divT : 'position:absolute;left:0;top:0;z-index:-1;overflow:hidden;width:100%;height:100%',
                ImgT:'position:absolute;left:0;top:0;z-index:-2;opacity:0;',
            }

     

  5. 封裝一些私有方法處理一些常用的方法,比如參數處理呀啥的
    //私有方法,不對外開放
            var privateMethods = {
                //對開發者的配置進行處理
                paraHandling:function(option){
                    var configTemp ;
                    if(option.config != undefined){  //開發者設置了值
                        option.config.imgArr== undefined ? option.config.imgArr =config.imgArr:null;
                        option.config.imgSecond== undefined ? option.config.imgSecond = config.imgSecond:null;
                        option.config.isRandom== undefined ? option.config.isRandom = config.isRandom:null;
                        configTemp = option.config;
                    }else{
                        configTemp = config;
                    };
                    return configTemp;
                },
                //針對IE9處理淡出效果,因為IE9不支持transition
                divFadeIn:function(option){
                    if(option.selector == undefined){
                        throw new Error("please select a id (div).")
                    }else{
                        var showTime =  Number(option.config.imgSecond);
                        var opacityValue = 0;  //設置opacity的屬性值
                        var divSelector = tool.id_selector(option.selector); //獲得div的ID
                        var temp = setInterval(function(){
                            opacityValue+=0.01;
                            divSelector.style.opacity = opacityValue;
                            if(opacityValue>1){
                                clearInterval(temp);
                            }
                        },showTime/100);  //針對ie9 用opacity配合setInterval定時函數來實現淡出的效果,注意控制刷新的頻率,給視覺上一種流暢的感覺
                    }
                },
                //創建內容主題
                createContent:function(option){
                    //設置ID
                    var divImg = tool.createElement("div");
                    var object_div = {
                        node:divImg,
                        attribute:[
                            {
                                key:"id",
                                value:"divShow"
                            },
                            {
                                key:"style",
                                value:css.divT
                            }
                        ]
                    };
                    tool.attr(object_div);
    
                    //設置img屬性
                    var img = tool.createElement("img");
                    var object_div = {
                        node:img,
                        attribute:[
                            {
                                key:"id",
                                value:"imgShow"
                            },
                            {
                                key:"style",
                                value:css.ImgT+"transition:opacity "+option.config.imgSecond/1000+"s ease",
                            }
                        ]
                    };
                    tool.attr(object_div);
                    divImg.appendChild(img);
                    document.body.appendChild(divImg);
                    privateMethods.delayLoadImg(option.config.imgArr[0]);
                },
                //延遲加載圖片
                delayLoadImg:function(img_src){
                    var img = new Image();
                    img.src = img_src;
                    img.onload = function(){
                        var temp = {
                            node:tool.id_selector("imgShow"),
                            attribute:[
                                {
                                    key:"src",
                                    value:img_src
                                }
                            ]
                        };
                        tool.attr(temp);
    
                        tool.id_selector("imgShow").style.opacity = 1;
                    }
    
                }
            }

     

  6. 最后再拋出的供給開發者使用的init方法,里面檢查一些參數和屬性
    //暴露給開發者使用的方法,可隨意拓展
            var publicMethods = {
                init:function(option){
                    if(arguments.length == 0){  //檢查參數
                        throw new Error("this method need a config object");
                    }else{
                        if(document.body.style.opacity == undefined){  //檢測是否支持opacity屬性 [即IE9及以上]
                            throw new Error("please use the browser of high version ");
                        }else {
                            option.config = privateMethods.paraHandling(option);
                            option.selector = "divShow";
                            //如果是IE9的話
                            if (document.body.style.transition == undefined) {
                                privateMethods.createContent(option);
                                privateMethods.divFadeIn(option);
                            } else {
                                privateMethods.createContent(option);
                            };
                        }
                    }
                }
            }

     

  7. 測試代碼
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    </body>
    </html>
    <script src="setBackgroundImage_js.js"></script>
    <script>
        +(function(){
            var temp ={
                config:{
                    imgArr:["http://z.k1982.com/show_img/201303/2013033012383895.jpg"],
                    imgSecond:3000
                }
            }
            gerry.setBackgroundImage.init(temp);
        })()
    </script>

     

總結與說明:

因為IE8下面的濾鏡比較麻煩,所以也沒有對IE8做處理,就IE9+ 因為支持透明屬性。移動端沒做過測試,不過應該可以使用,因為針對移動端的話就更加簡單了,因為現在移動端的趨勢都是相對來說支持一些普遍的html5和css3的熟悉的。其實上面代碼中主要講的思想和對ie9做的兼容性,因為不可以使用第三方庫了,所以就自己寫了。整個代碼我也不貼了,直接放到github上了,希望大家點顆星贊一個,得到人的賞識還是很有動力的。

 

github地址:https://github.com/GerryIsWarrior/setBackgroundImage_js

 


免責聲明!

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



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