欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)跑馬燈抽獎活動實(shí)例代碼解析與優(yōu)化(二)

 更新時間:2016年02月16日 14:03:12   作者:zhiqiang21  
這篇文章主要介紹了JavaScript實(shí)現(xiàn)跑馬燈抽獎活動實(shí)例代碼解析與優(yōu)化(二)的相關(guān)資料,需要的朋友可以參考下

在上篇文章給大家介紹了JavaScript實(shí)現(xiàn)跑馬燈抽獎活動實(shí)例代碼解析與優(yōu)化(一),既然是要編寫插件。那么叫做“插件”的東西肯定是具有的某些特征能夠滿足我們平時開發(fā)的需求或者是提高我們的開發(fā)效率。那么叫做插件的東西應(yīng)該具有哪些基本特征呢?讓我們來總結(jié)一下:

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

配置一定要簡單
插件中定義的變量不污染全局變量;
同一段代碼可以在不同的地方復(fù)用;
用戶可以自定義自己功能參數(shù);
具有銷毀變量和參數(shù)的功能;
如果按照以上的幾個特征來寫插件的話,我們可以總結(jié)出一個基本的代碼結(jié)構(gòu),我們一個一個的來看:

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

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

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

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

$(function() {
//這里的 test 是代表容器的 class
window.LightRotate.init($('[node-type=reward-area]'));
});

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

JavaScript 具有塊級作用域的標(biāo)識符就是function了。那我們怎么聲明我們的變量才可以使它不污染全局變量呢?
這里我們需要用到的一個 JavaScript 函數(shù)的自執(zhí)行的知識點(diǎn)。代碼如下:

(function(){
// do something
})();

3.在不同的地方復(fù)用功能代碼

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

//
(function($){
// 創(chuàng)建功能對象
var LightRotate = function (select) {
// do something
};
LightRotate.init = function (select) {
var _this = this;
//根據(jù)不同的容器實(shí)例化不同的對象
select.each(function () {
new _this($(this));
});
};
window.LightRotate = LightRotate;
})(jQuery);

4.用戶可以自定義功能參數(shù)

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

//
(function($){
// 創(chuàng)建功能對象
var LightRotate = function (select) {
// 自定義的參數(shù)
this.setting = {
liAutoPlay: false, //周圍的燈是否自動旋轉(zhuǎn)
roLiSpeed: 100, //燈旋轉(zhuǎn)的速度ms
roPrSpeed: 200, //獎品旋轉(zhuǎn)速度ms
liDirection: true, //旋轉(zhuǎn)方向 true 正方向 false 反方向
randomPrize: false //空格是否隨機(jī)選取
};
};
LightRotate.init = function (select) {
var _this = this;
//根據(jù)不同的容器實(shí)例化不同的對象
select.each(function () {
new _this($(this));
});
};
window.LightRotate = LightRotate;
})(jQuery);

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

<div class="re-area" node-type="reward-area" data-setting='{
"liAutoPlay":false,
"roLiSpeed":100,
"roPrSpeed":200,
"liDirection":true,
"randomPrize":false}'>

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

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

//
(function($){
// 創(chuàng)建功能對象
var LightRotate = function (select) {
// 自定義的參數(shù)
this.setting = {
liAutoPlay: false, //周圍的燈是否自動旋轉(zhuǎn)
roLiSpeed: 100, //燈旋轉(zhuǎn)的速度ms
roPrSpeed: 200, //獎品旋轉(zhuǎn)速度ms
liDirection: true, //旋轉(zhuǎn)方向 true 正方向 false 反方向
randomPrize: false //空格是否隨機(jī)選取
};
//這里調(diào)用對象的獲取用戶自定義參數(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í)例化不同的對象
select.each(function () {
new _this($(this));
});
};
window.LightRotate = LightRotate;
})(jQuery);

5.銷毀變量和參數(shù)的功能;

最后一個就是我們的插件應(yīng)該具有銷毀自身變量和參數(shù)的功能。我們該怎么寫呢?還是在上面的代碼基礎(chǔ)上繼續(xù)擴(kuò)展功能對象的可調(diào)用方法,代碼如下:

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

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

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

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

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

如果一段代碼運(yùn)行效率很低,就會影響后續(xù)代碼的執(zhí)行。所以對于 JavaScript ,代碼優(yōu)化是必須的。
先來看看我們的“跑馬燈”插件應(yīng)該具有哪些功能:

能夠控制燈是否自動播放;
燈的旋轉(zhuǎn)方向可以控制;
燈的旋轉(zhuǎn)速度可以控制;
獎品的旋轉(zhuǎn)速度可以控制;
這里就不詳細(xì)的介紹這些功能點(diǎn)的開發(fā)過程,僅僅介紹優(yōu)化過程。如果有興趣可以看我文章最后附上的源代碼地址,進(jìn)行下載閱讀。

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

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

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

//獲取外圍的燈,可以看到我這里使用的選擇器多了一個 select,是為了獲取當(dāng)前容器下的某些元素,避免有多個容器存在時沖突
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)椤跋隆焙汀白蟆狈较虻臒羰切枰剐虻?,所以我使用了兩個倒序的 for循環(huán),其實(shí)當(dāng)循環(huán)出現(xiàn)的時候,我們都應(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對象的reverse方法。

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

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

給每一個“燈”(注意,這里是每一個,罪過…罪過…)定義一個setTimeout(),執(zhí)行時間就是數(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個“燈”那么就會在當(dāng)前的 js 執(zhí)行隊(duì)列中加入100個setTimeout(),再次強(qiáng)調(diào)的是我這里又使用了for循環(huán),在時間復(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)兩個優(yōu)點(diǎn):第一,就是減少了 for循環(huán)的使用,降低了代碼的時間復(fù)雜度,第二就是,每次我僅僅在當(dāng)前代碼執(zhí)行的隊(duì)列中創(chuàng)建一個setInterval()。減小了執(zhí)行隊(duì)列的復(fù)雜度。

關(guān)于JavaScript實(shí)現(xiàn)跑馬燈抽獎活動實(shí)例代碼解析與優(yōu)化(二)的相關(guān)知識就給大家介紹到這里,希望本文所述對大家有所幫助。

相關(guān)文章

  • 微信小程序?qū)崿F(xiàn)圖片選擇并預(yù)覽功能

    微信小程序?qū)崿F(xiàn)圖片選擇并預(yù)覽功能

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)圖片選擇并預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • javascript函數(shù)自動執(zhí)行常用方法匯總

    javascript函數(shù)自動執(zhí)行常用方法匯總

    本文給大家匯總介紹了3種javascript函數(shù)自動執(zhí)行的常用方法,非常的簡單實(shí)用,有需要的小伙伴可以參考下
    2016-03-03
  • 關(guān)于JavaScript遞歸經(jīng)典案例題詳析

    關(guān)于JavaScript遞歸經(jīng)典案例題詳析

    遞歸是算法中一個重要的解法,因此,有必要單拎出來講講,所以下面這篇文章主要給大家介紹了關(guān)于JavaScript遞歸經(jīng)典案例題的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • 可能被忽略的一些JavaScript數(shù)組方法細(xì)節(jié)

    可能被忽略的一些JavaScript數(shù)組方法細(xì)節(jié)

    這篇文章主要給大家介紹了一些可能被忽略的JavaScript數(shù)組方法細(xì)節(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • js學(xué)習(xí)階段總結(jié)(必看篇)

    js學(xué)習(xí)階段總結(jié)(必看篇)

    下面小編就為大家?guī)硪黄猨s學(xué)習(xí)階段總結(jié)(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • JS中splice添加或刪除數(shù)組元素

    JS中splice添加或刪除數(shù)組元素

    本文主要介紹了JS中splice添加或刪除數(shù)組元素,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • webpack代碼分片的實(shí)現(xiàn)

    webpack代碼分片的實(shí)現(xiàn)

    代碼分片是webpck打包工具所特有的一項(xiàng)技術(shù),通過這項(xiàng)功能可以把代碼按照特定的形式進(jìn)行拆分,使用戶不必一次全部加載,而是按需加載。本文就來詳細(xì)介紹,感興趣的可以了解一下
    2021-07-07
  • 對于input 框限定輸入值為浮點(diǎn)型的js代碼

    對于input 框限定輸入值為浮點(diǎn)型的js代碼

    下面小編就為大家?guī)硪黄獙τ趇nput 框限定輸入值為浮點(diǎn)型的js代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • bootstrap+jQuery 實(shí)現(xiàn)下拉菜單中復(fù)選框全選和全不選效果

    bootstrap+jQuery 實(shí)現(xiàn)下拉菜單中復(fù)選框全選和全不選效果

    這篇文章主要給大家介紹了關(guān)于利用bootstrap+jQuery 實(shí)現(xiàn)下拉菜單中復(fù)選框全選和全不選效果的相關(guān)資料,文中給出了完整的示例代碼供大家參考學(xué)習(xí),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友下面來一起看看吧。
    2017-06-06
  • js面試題之異步問題的深入理解

    js面試題之異步問題的深入理解

    這篇文章主要給大家介紹了關(guān)于js面試題之異步問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評論