成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript “跑馬燈”抽獎(jiǎng)活動(dòng)代碼解析與優(yōu)化(二)

vincent_xyb / 1644人閱讀

摘要:我的第一版是這樣做的因?yàn)橄潞妥蠓较虻臒羰切枰剐虻模晕沂褂昧藘蓚€(gè)倒序的循環(huán),其實(shí)當(dāng)循環(huán)出現(xiàn)的時(shí)候,我們都應(yīng)該思考我們的代碼是否有可優(yōu)化的空間。到這里關(guān)于跑馬燈插件的代碼解析詳和優(yōu)化就已經(jīng)完了。

既然是要編寫插件。那么叫做“插件”的東西肯定是具有的某些特征能夠滿足我們平時(shí)開發(fā)的需求或者是提高我們的開發(fā)效率。那么叫做插件的東西應(yīng)該具有哪些基本特征呢?讓我們來總結(jié)一下:

1.JavaScript 插件一些基本特征:

配置一定要簡單

插件中定義的變量不污染全局變量;

同一段代碼可以在不同的地方復(fù)用;

用戶可以自定義自己功能參數(shù);

具有銷毀變量和參數(shù)的功能;

如果按照以上的幾個(gè)特征來寫插件的話,我們可以總結(jié)出一個(gè)基本的代碼結(jié)構(gòu),我們一個(gè)一個(gè)的來看:

1.插件配置要盡可能的簡單

html中配置容器節(jié)點(diǎn)

//這里的node-type="reward-area" 是標(biāo)識(shí)我們插件的容器節(jié)點(diǎn)

DOM加載完成以后初始化插件

$(function() {
    //這里的 test 是代表容器的 class
    window.LightRotate.init($("[node-type=reward-area]"));
});
2.插件中定義的變量不污染全局變量

JavaScript 具有塊級(jí)作用域的標(biāo)識(shí)符就是function了。那我們?cè)趺绰暶魑覀兊淖兞坎趴梢允顾晃廴救肿兞磕兀?br>這里我們需要用到的一個(gè) JavaScript 函數(shù)的自執(zhí)行的知識(shí)點(diǎn)。代碼如下:

(function(){
    // do something
})();
3.在不同的地方復(fù)用功能代碼

這就要用到我們面向?qū)ο蟮闹R(shí)點(diǎn),把我們的功能代碼抽象成對(duì)象,在我們需要使用的時(shí)候,實(shí)例化對(duì)象就可以了。那我們接著第二部的代碼繼續(xù)寫,

//
(function($){
    // 創(chuàng)建功能對(duì)象
    var LightRotate = function (select) {
        // do something
    };

    LightRotate.init = function (select) {
        var _this = this;
        //根據(jù)不同的容器實(shí)例化不同的對(duì)象
        select.each(function () {
            new _this($(this));
        });
    };

    window.LightRotate = LightRotate;
})(jQuery);
4.用戶可以自定義功能參數(shù)

首先我們應(yīng)該有默認(rèn)的參數(shù)設(shè)定,比如下面這樣

//
(function($){
    // 創(chuàng)建功能對(duì)象
    var LightRotate = function (select) {
        // 自定義的參數(shù)
        this.setting = {
            liAutoPlay: false,  //周圍的燈是否自動(dòng)旋轉(zhuǎn)
            roLiSpeed: 100,     //燈旋轉(zhuǎn)的速度ms
            roPrSpeed: 200,     //獎(jiǎng)品旋轉(zhuǎn)速度ms
            liDirection: true,  //旋轉(zhuǎn)方向 true  正方向   false  反方向
            randomPrize: false  //空格是否隨機(jī)選取
        };
    };

    LightRotate.init = function (select) {
        var _this = this;
        //根據(jù)不同的容器實(shí)例化不同的對(duì)象
        select.each(function () {
            new _this($(this));
        });
    };

    window.LightRotate = LightRotate;
})(jQuery);

其實(shí)這樣寫的話,使用者已經(jīng)可以修改我們的 JavaScript 文件來完成自定義了。但是為了能夠讓我們的差價(jià)足夠的好用,比如說,我們的使用者一點(diǎn)兒都不懂 js 呢?該怎么辦?
這樣我們可以把這些參數(shù)用自定義屬性配置在 html中,如下:

這樣用戶只需要在 html的節(jié)點(diǎn)中就可以配置當(dāng)前容器運(yùn)行的參數(shù)。這樣的好處還可以使同一頁面上的不同容器,可以多帶帶的配置參數(shù),減少耦合。

那么在 js 中我們?cè)撛趺传@取這些參數(shù)呢?在上面的代碼中,已經(jīng)有了功能對(duì)象函數(shù)。那么我們想擴(kuò)展對(duì)象方法來獲取用戶的自定義參數(shù),怎么辦呢?我們一般使用prototype的東西來擴(kuò)展我們已有對(duì)象的方法,代碼如下:

//
(function($){
    // 創(chuàng)建功能對(duì)象
    var LightRotate = function (select) {
        // 自定義的參數(shù)
        this.setting = {
            liAutoPlay: false,  //周圍的燈是否自動(dòng)旋轉(zhuǎn)
            roLiSpeed: 100,     //燈旋轉(zhuǎn)的速度ms
            roPrSpeed: 200,     //獎(jiǎng)品旋轉(zhuǎn)速度ms
            liDirection: true,  //旋轉(zhuǎn)方向 true  正方向   false  反方向
            randomPrize: false  //空格是否隨機(jī)選取
        };
        
        //這里調(diào)用對(duì)象的獲取用戶自定義參數(shù)的方法,并且將默認(rèn)參數(shù)合并
        $.extend(_this.setting, _this.getSettingUser());
    };

    LightRotate.prototype = {
        //擴(kuò)展獲取用戶自定義參數(shù)的方法
        getSettingUser: function () {
            var userSetting = this.LightArea.attr("data-setting");
            if (userSetting && userSetting !== "") {
                return $.parseJSON(userSetting);
            } else {
                return {};
            }
        }
    };

    LightRotate.init = function (select) {
        var _this = this;
        //根據(jù)不同的容器實(shí)例化不同的對(duì)象
        select.each(function () {
            new _this($(this));
        });
    };

    window.LightRotate = LightRotate;
})(jQuery);
5.銷毀變量和參數(shù)的功能;

最后一個(gè)就是我們的插件應(yīng)該具有銷毀自身變量和參數(shù)的功能。我們?cè)撛趺磳懩兀窟€是在上面的代碼基礎(chǔ)上繼續(xù)擴(kuò)展功能對(duì)象的可調(diào)用方法,代碼如下:

LightRotate.prototype = {
        //擴(kuò)展獲取用戶自定義參數(shù)的方法
        getSettingUser: function () {
            var userSetting = this.LightArea.attr("data-setting");
            if (userSetting && userSetting !== "") {
                return $.parseJSON(userSetting);
            } else {
                return {};
            }
        },
        //銷毀對(duì)象參數(shù)
        destory: function () {
            $(_this.LightArea).off();
            this.closeAnimation();
            this.rewardTimer = null;
        }
    };

由以上我們的內(nèi)容我們可以大概了解了一個(gè)成熟的插件應(yīng)該具有的基本功能。

2.插件開發(fā)和優(yōu)化示例

剛好這個(gè)項(xiàng)目是在春節(jié)放假前的一個(gè)緊急的項(xiàng)目,當(dāng)時(shí)為了趕進(jìn)度就沒有詳細(xì)思考自己的代碼結(jié)構(gòu),這樣野味自己的后續(xù)優(yōu)化提供了機(jī)會(huì)。

由上一節(jié)介紹的定時(shí)器的內(nèi)容可以知道 JavaScript 是單線程的。所以

如果一段代碼運(yùn)行效率很低,就會(huì)影響后續(xù)代碼的執(zhí)行。所以對(duì)于 JavaScript ,代碼優(yōu)化是必須的。

先來看看我們的“跑馬燈”插件應(yīng)該具有哪些功能:

能夠控制燈是否自動(dòng)播放;

燈的旋轉(zhuǎn)方向可以控制;

燈的旋轉(zhuǎn)速度可以控制;

獎(jiǎng)品的旋轉(zhuǎn)速度可以控制;

這里就不詳細(xì)的介紹這些功能點(diǎn)的開發(fā)過程,僅僅介紹優(yōu)化過程。如果有興趣可以看我文章最后附上的源代碼地址,進(jìn)行下載閱讀。

1.“順序”獲取旋轉(zhuǎn)燈代碼的優(yōu)化

因?yàn)橹車臒粑沂鞘褂媒^對(duì)定位來做的,所以我需要“順序”的獲取他們的列表,然后操作。

首先獲取 DOM節(jié)點(diǎn)。

//獲取外圍的燈,可以看到我這里使用的選擇器多了一個(gè) select,是為了獲取當(dāng)前容器下的某些元素,避免有多個(gè)容器存在時(shí)沖突
this.topLight = $("[node-type=re-top]", select).find("span");
this.rightLight = $("[node-type=re-right]", select).find("span");
this.bottomLight = $("[node-type=re-bottom]", select).find("span");
this.leftLight = $("[node-type=re-left]", select).find("span");

然后就應(yīng)該“順序”的獲取“燈”節(jié)點(diǎn)的 DOM 元素列表。

我的第一版是這樣做的:

Zepto(topLight).each(function() {
      lightList.push(this);
});

Zepto(rightLight).each(function() {
      lightList.push(this);
});

for (var j = bottomLight.length - 1; j >= 0; j--) {
     lightList.push(bottomLight[j]);
}

for (var m = leftLight.length - 1; m >= 0; m--) {
       lightList.push(leftLight[m]);
}

因?yàn)椤跋隆焙汀白蟆狈较虻臒羰切枰剐虻?,所以我使用了兩個(gè)倒序的 for循環(huán),其實(shí)當(dāng)循環(huán)出現(xiàn)的時(shí)候,我們都應(yīng)該思考我們的代碼是否有可優(yōu)化的空間。

優(yōu)化后的代碼是這樣子的,在這里我減少了4次循環(huán)的使用

function () {
    var lightList = [];
    var bottomRever;
    var leftRever;
     bottomRever = Array.from(this.bottomLight).reverse();
     leftRever = Array.from(this.leftLight).reverse();

     lightList = Array.from(this.topLight).concat(Array.from(this.rightLight));
     lightList = lightList.concat(bottomRever);
     lightList = lightList.concat(leftRever);
     }

列表倒序我使用了原生 Array對(duì)象的reverse方法。

2.使用“閉包”優(yōu)化順序循環(huán)播放

為了能夠使我們的“燈”順序的跑起來,第一版的思路是:

每一個(gè)“燈”(注意,這里是每一個(gè),罪過...罪過...)定義一個(gè)setTimeout(),執(zhí)行時(shí)間就是數(shù)序的加入 js 執(zhí)行隊(duì)列中去。

代碼是下面這樣子的:

            var zepto_light = Zepto(lightList);
            var changeTime = 100;
            var lightLength = zepto_light.length;
            var totleTime = changeTime * lightLength;

            function lightOpen() {
                for (var i = 0; i < lightLength; i++) {
                    (function temp(i) {
                        lightTimer = setTimeout(function() {
                            if (stopAnimation === false) {
                                Zepto(zepto_light).removeClass("light_open");
                                Zepto(zepto_light[i]).addClass("light_open");
                            } else {
                                return;
                            }
                        }, changeTime * i);
                    })(i);
                }
            }

這樣子寫的缺點(diǎn)很明顯:如果我有100個(gè)“燈”那么就會(huì)在當(dāng)前的 js 執(zhí)行隊(duì)列中加入100個(gè)setTimeout(),再次強(qiáng)調(diào)的是我這里又使用了for循環(huán),在時(shí)間復(fù)雜度上又增加了。代碼的執(zhí)行效率又下降了。

后來思考了下,JavaScript 中“閉包”符合我當(dāng)前的使用場景,就想著用閉包優(yōu)化一下,優(yōu)化后代碼如下:

lightRun: function () {
            var _this = this;
            function tempFunc() {
                var lightList = _this.getLightList();
                var lightLength = lightList.length;
                var i = 0;
                return function () {

                    $(lightList, _this.LightArea).removeClass("light_open");
                    $(lightList[i], _this.LightArea).addClass("light_open");
                    i++;

                    //使一輪循環(huán)結(jié)束后能夠繼續(xù)下次循環(huán)
                    if (i === lightLength) {
                        i = 0;
                    }
                };
            }

            var lightRunFunc = tempFunc();
            lightRunFunc();
            _this.lightInterVal = setInterval(lightRunFunc, _this.setting.roLiSpeed);
        }

由以上的代碼可以很明顯的發(fā)現(xiàn)兩個(gè)優(yōu)點(diǎn):第一,就是減少了 for循環(huán)的使用,降低了代碼的時(shí)間復(fù)雜度,第二就是,每次我僅僅在當(dāng)前代碼執(zhí)行的隊(duì)列中創(chuàng)建一個(gè)setInterval()。減小了執(zhí)行隊(duì)列的復(fù)雜度。

到這里關(guān)于“跑馬燈”插件的代碼解析詳和優(yōu)化就已經(jīng)完了。詳細(xì)的代碼和使用文檔請(qǐng)點(diǎn)擊鏈接。如果有什么問題可以隨時(shí)在 github 上反饋給我。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/49745.html

相關(guān)文章

  • JavaScript跑馬燈抽獎(jiǎng)活動(dòng)代碼解析優(yōu)化

    摘要:我的第一版是這樣做的因?yàn)橄潞妥蠓较虻臒羰切枰剐虻?,所以我使用了兩個(gè)倒序的循環(huán),其實(shí)當(dāng)循環(huán)出現(xiàn)的時(shí)候,我們都應(yīng)該思考我們的代碼是否有可優(yōu)化的空間。到這里關(guān)于跑馬燈插件的代碼解析詳和優(yōu)化就已經(jīng)完了。 既然是要編寫插件。那么叫做插件的東西肯定是具有的某些特征能夠滿足我們平時(shí)開發(fā)的需求或者是提高我們的開發(fā)效率。那么叫做插件的東西應(yīng)該具有哪些基本特征呢?讓我們來總結(jié)一下: 1.JavaScri...

    Muninn 評(píng)論0 收藏0
  • JavaScript跑馬燈抽獎(jiǎng)活動(dòng)代碼解析優(yōu)化

    摘要:我的第一版是這樣做的因?yàn)橄潞妥蠓较虻臒羰切枰剐虻?,所以我使用了兩個(gè)倒序的循環(huán),其實(shí)當(dāng)循環(huán)出現(xiàn)的時(shí)候,我們都應(yīng)該思考我們的代碼是否有可優(yōu)化的空間。到這里關(guān)于跑馬燈插件的代碼解析詳和優(yōu)化就已經(jīng)完了。 既然是要編寫插件。那么叫做插件的東西肯定是具有的某些特征能夠滿足我們平時(shí)開發(fā)的需求或者是提高我們的開發(fā)效率。那么叫做插件的東西應(yīng)該具有哪些基本特征呢?讓我們來總結(jié)一下: 1.JavaScri...

    Yi_Zhi_Yu 評(píng)論0 收藏0
  • JavaScript跑馬燈抽獎(jiǎng)活動(dòng)代碼解析優(yōu)化(一)

    摘要:最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。這里主要是來寫寫自己的優(yōu)化過程。所以寫代碼的時(shí)候一定要注意一些小細(xì)節(jié)哈。。。在以后,其返回的元素順序等同于在中出現(xiàn)的先后順序。盡管是一個(gè)數(shù)組。這時(shí)從加入執(zhí)行隊(duì)列到加入執(zhí)行隊(duì)列中間時(shí)間間隔是。 最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。上篇文章已經(jīng)分享過html和css 的相關(guān)知識(shí)。這篇文章主要分享一些 JavaScript 相關(guān)的知識(shí)。這幾天在...

    isaced 評(píng)論0 收藏0
  • JavaScript跑馬燈抽獎(jiǎng)活動(dòng)代碼解析優(yōu)化(一)

    摘要:最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。這里主要是來寫寫自己的優(yōu)化過程。所以寫代碼的時(shí)候一定要注意一些小細(xì)節(jié)哈。。。在以后,其返回的元素順序等同于在中出現(xiàn)的先后順序。盡管是一個(gè)數(shù)組。這時(shí)從加入執(zhí)行隊(duì)列到加入執(zhí)行隊(duì)列中間時(shí)間間隔是。 最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。上篇文章已經(jīng)分享過html和css 的相關(guān)知識(shí)。這篇文章主要分享一些 JavaScript 相關(guān)的知識(shí)。這幾天在...

    MRZYD 評(píng)論0 收藏0
  • JavaScript跑馬燈抽獎(jiǎng)活動(dòng)代碼解析優(yōu)化(一)

    摘要:最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。這里主要是來寫寫自己的優(yōu)化過程。所以寫代碼的時(shí)候一定要注意一些小細(xì)節(jié)哈。。。在以后,其返回的元素順序等同于在中出現(xiàn)的先后順序。盡管是一個(gè)數(shù)組。這時(shí)從加入執(zhí)行隊(duì)列到加入執(zhí)行隊(duì)列中間時(shí)間間隔是。 最近的項(xiàng)目中做了一個(gè)跑馬燈的抽獎(jiǎng)特效插件。上篇文章已經(jīng)分享過html和css 的相關(guān)知識(shí)。這篇文章主要分享一些 JavaScript 相關(guān)的知識(shí)。這幾天在...

    HelKyle 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<