手把手教你封裝JavaScript插件

我們可能已經(jīng)用過很多JS插件,比如著名的輪播圖插件Swiper.js,滾動條插件iScroll.js等等臀蛛,用起來非常方便尿扯,大大提高了我們的工作效率求晶。那么它們基本實現(xiàn)原理是怎樣的呢?我們又該如何DIY一個可以復(fù)用的JS插件呢衷笋?

接下來芳杏,我將以圖片無縫循環(huán)輪播為例,手把手教你封裝一個方便復(fù)用的原生JS插件辟宗。

開始之前爵赵,我們先看看實現(xiàn)后的具體效果吧 → 圖片無縫循環(huán)輪播

一泊脐、面向過程編程實現(xiàn)

1. 實現(xiàn)原理

圖片無縫循環(huán)輪播

如上圖所示空幻,后三個 li 元素為復(fù)制元素,container 保持不動容客,ul 向左移動秕铛,當(dāng)狀態(tài)到達(dá)②時瞬間切回①狀態(tài)则剃,這樣整個過程看起來就像一直向左移動一樣。

2. 實現(xiàn)代碼

/*CSS*/
html{ background-color: #00b0e4;}
body,ul,li{ margin: 0; padding: 0;}
ul li{ list-style: none;}
.container{ height: 300px; margin: 100px auto; padding: 60px 0; overflow: hidden;}
.container ul{ display: -webkit-flex; display: flex; height: 100%;}
.container ul li{ -webkit-flex-shrink: 0; flex-shrink: 0; position: relative; z-index: 0; width: 400px; height: 100%; 
padding: 5px; box-sizing: border-box; -webkit-transition: all .6s; transition: all .6s;}
.container ul li:hover{ z-index: 1; -webkit-transform: scale(1.2); transform: scale(1.2); }
.container ul li img{ width: 100%; height: 100%; object-fit: cover; box-sizing: border-box; 
border: 10px solid #fff; box-shadow: 0 0 5px #333;}

布局方式我使用的是flexbox布局如捅,可以輕松實現(xiàn)圖片橫排棍现,更多相關(guān)內(nèi)容請戳 → 快速理解Flexbox布局

圖片樣式中我用到了object-fit: cover镜遣,這個屬性可以使不同比例的圖片在寬高固定的情況下不被壓縮變形己肮,更多相關(guān)內(nèi)容請戳 → 圖片在固定寬高盒子中的顯示問題

<!--HTML-->
<div class="container">
    <ul class="wrapper">
        <li class="slide"><img src="./imgs/1.jpg" alt=""></li>
        <li class="slide"><img src="./imgs/2.jpg" alt=""></li>
        <li class="slide"><img src="./imgs/3.jpg" alt=""></li>
        <li class="slide"><img src="./imgs/4.jpg" alt=""></li>
    </ul>
</div>
// Javascript
window.onload = function () {

    var oContainer = document.querySelector('.container'),
        oWrapper = oContainer.querySelector('ul'),
        oSlide = oWrapper.querySelectorAll('li');

    var wrapperW = oSlide[0].offsetWidth * oSlide.length;
    oWrapper.style.width = wrapperW * 2 + 'px';

    // 復(fù)制所有圖片以實現(xiàn)圖片無縫銜接
    oWrapper.innerHTML += oWrapper.innerHTML;

    /*此處是為了防止所有圖片總寬度小于最外層盒子的寬度,
      這時需要將最外層盒子寬度設(shè)置為圖片總寬度*/
    if(wrapperW < oContainer.offsetWidth){
        oContainer.style.width = wrapperW + 'px';
    }

    var x = 0, timer = null;

    // 圖片自動輪播函數(shù)
    var slideMove = function(){
        timer = setInterval(function () {
            x++;
            if(x > wrapperW){
                x = 0;
            }
            // 圖片左移
            oWrapper.style.transform = 'translate('+ (-x) +'px)';
        },10);
    };

    // 圖片自動無限輪播
    slideMove();

    // 鼠標(biāo)移入時清除定時器悲关,圖片停止輪播
    oContainer.addEventListener('mouseover',function () {
        clearInterval(timer);
    });

    // 鼠標(biāo)移出時圖片繼續(xù)輪播
    oContainer.addEventListener('mouseout',function () {
        slideMove();
    });

};

二谎僻、面向?qū)ο缶幊虒崿F(xiàn)

1. 基本改造步驟

如何將面向過程改造成面向?qū)ο?/strong>呢?

一般有以下幾個基本步驟:

① 創(chuàng)建一個構(gòu)造函數(shù)
② 變量改為屬性
③ 函數(shù)改為原型方法(有些實現(xiàn)某塊具體功能的代碼也可抽離成原型方法)
④ 更正某些不正確的this指向

2. 實現(xiàn)代碼

// Javascript

/* 創(chuàng)建一個構(gòu)造函數(shù) */
function FreeSlider(selector,speed) {

    /* 變量改為屬性 */
    this.oContainer = document.querySelector(selector);
    this.oWrapper = this.oContainer.querySelector('ul');
    this.oSlide = this.oWrapper.querySelectorAll('li');

    /* 當(dāng)不傳入輪播速度時寓辱,速度默認(rèn)為100 */
    this.speed = speed || 100;

    this.containerW = this.oContainer.offsetWidth;
    this.wrapperW = this.oSlide[0].offsetWidth * this.oSlide.length;
    this.x = 0;
    this.timer = null;

    this.init();

}

/* 構(gòu)造函數(shù)的原型對象 */
FreeSlider.prototype = {

    constructor: FreeSlider,

    /* 功能抽離艘绍,此處實現(xiàn)初始化 */
    init: function(){
        this.oWrapper.style.width = this.wrapperW * 2 + 'px';
        this.oWrapper.innerHTML += this.oWrapper.innerHTML;

        if(this.wrapperW < this.containerW){
            this.oContainer.style.width = this.wrapperW + 'px';
        }

        this.slideMove();
    },

     /* 圖片自動無限輪播 */
    slideMove: function(){
        /* 此處需要注意this的指向,
           在setInterval回調(diào)函數(shù)中的this指向為window */
        var that = this;  
        this.timer = setInterval(function () {
            that.x++;
            if(that.x > that.wrapperW){
                that.x = 0;
            }
            that.oWrapper.style.transform = 'translate('+ (-that.x) +'px)';
        },this.containerW / this.speed);   // 將速度轉(zhuǎn)化成定時器時間
    },

    /* 圖片停止輪播 */
    stopSlideMove: function () {
        clearInterval(this.timer);
    }
};

window.onload = function(){

    var oContainer = document.querySelector('.container');

    // 新建圖片輪播對象
    var mySlider = new FreeSlider('.container',300);

    // 鼠標(biāo)移入時清除定時器秫筏,圖片停止輪播
    oContainer.addEventListener('mouseover',function () {
        mySlider.stopSlideMove();
    });

    // 鼠標(biāo)移出時圖片繼續(xù)輪播
    oContainer.addEventListener('mouseout',function () {
        mySlider.slideMove();
    });

}

本文重點總結(jié)

① JS插件其實沒有你想象的那么難诱鞠,基本原理就是面向?qū)ο?br> ② 將需要可靈活配置的部分作為構(gòu)造函數(shù)的參數(shù)傳入,插件中的各個功能可作為原型方法提供給外部調(diào)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末这敬,一起剝皮案震驚了整個濱河市航夺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌崔涂,老刑警劉巖阳掐,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異冷蚂,居然都是意外死亡缭保,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門蝙茶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艺骂,“玉大人,你說我怎么就攤上這事尸闸〕骨祝” “怎么了孕锄?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵吮廉,是天一觀的道長。 經(jīng)常有香客問我畸肆,道長宦芦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任轴脐,我火速辦了婚禮调卑,結(jié)果婚禮上抡砂,老公的妹妹穿的比我還像新娘。我一直安慰自己恬涧,他們只是感情好注益,可當(dāng)我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溯捆,像睡著了一般丑搔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上提揍,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天啤月,我揣著相機與錄音,去河邊找鬼劳跃。 笑死谎仲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刨仑。 我是一名探鬼主播郑诺,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杉武!你這毒婦竟也來了间景?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤艺智,失蹤者是張志新(化名)和其女友劉穎倘要,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體十拣,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡封拧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了夭问。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泽西。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缰趋,靈堂內(nèi)的尸體忽然破棺而出捧杉,到底是詐尸還是另有隱情,我是刑警寧澤秘血,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布味抖,位于F島的核電站,受9級特大地震影響灰粮,放射性物質(zhì)發(fā)生泄漏仔涩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一粘舟、第九天 我趴在偏房一處隱蔽的房頂上張望熔脂。 院中可真熱鬧佩研,春花似錦、人聲如沸霞揉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽适秩。三九已至袍暴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間隶症,已是汗流浹背政模。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚂会,地道東北人淋样。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像胁住,于是被迫代替她去往敵國和親趁猴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1彪见、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,988評論 3 119
  • 這條路儡司,連接著我所住的單身公寓和公司,每周七天余指,星夜未眠捕犬,上班上班,還是上班酵镜。 畢業(yè)一年碉碉,工作一年,這條路...
    陌路之隱閱讀 283評論 0 1
  • 對自由的美好想象莫過于睡到自然醒淮韭,不用上班不用干活垢粮,沒有約束想干什么就干什么】糠啵或者是說每天不用為工作忙碌蜡吧,喝喝茶,...
    大軒小程閱讀 447評論 0 0
  • 愛,其實很簡單捞慌。 今天是圣誕節(jié)耀鸦,公司同事都放假了,可是我們部門還要上班啸澡,偏偏下午電腦又出了故障袖订,技術(shù)部人又放假,只...
    藏著不等于遺忘閱讀 217評論 0 0