一個簡單的選項卡js插件

估計大概兩三個月沒有這類的關于前端的文章了,一來是覺得自己太菜,二來也是因為自己的懶散,渾渾噩噩的消耗時間卻沒有收獲什么成果。今天因為和一些同學的聊天,突然自己的心情很低落,有一種看不到未來在哪的感覺,所以強行讓自己學習,去看js插件怎么寫。今天寫一個簡單的選項卡插件,這個我也是看別人博文學習實現(xiàn)的,然后加一些自己的理解。

一.實現(xiàn)效果

選項卡切換
實現(xiàn)頁面的代碼

雖說有點簡陋,但是可以看到在html文件中,引入我們寫的tab.js插件后,實現(xiàn)選項卡切換,就只需一行代碼就可以實現(xiàn)了。

二.tab.js結構

先整體看下結構大概是怎樣

//一開始當然是創(chuàng)建一個構造函數(shù)tab
function Tab(){
  //里面只有一行代碼,就是調用自身的初始化方法
  this.init.apply(this,arguments);
}

//需要的屬性和方法全部寫在prototype里面
Tab.prototype = {
  //屬性
  //some code
  //方法
  //some code
}

三.一些方法的實現(xiàn)

  1. 我們在這里沒有使用閉包然后立即執(zhí)行,所以才需要一個初始化函數(shù)將屬性都初始化,在init中:
  init:function(ela,elb,paramObj){
  //一般在插件中都會有個配置對象,并且有默認值
  this.defaultOptions = {
    curClass:'current',
    type:'mouseover',
    delay:150
  }
  //然后我們會去檢測用戶有沒有傳入配置參數(shù),有的話就要使用用戶的配置,這里使用到一個extend方法
  this.options = this.extend(this.defaultOptions, paramObj || {})
}

extend實際是一個對象拓展方法,將b對象的屬性覆蓋到a對象中,在JQ里直接寫好了這種方法,但js里沒有,需要我們自己去模擬,我們將這個方法寫在init外面

extend:function(a,b){
  for(var i in b){
    //這個是檢測for循環(huán)到的屬性是不是b自身的
    if(b.hasOwnProperty(i)){
      a[i] = b[i]
    }
  }
  return a;
}

后面init里就是一些基本的屬性,比如獲取導航欄的DOM,內容塊的DOM,以及他們的子元素還有子元素的個數(shù),后面遍歷會用到,具體可在文章附的源碼里去看。最后我們要在init中給每個導航綁定事件,一個是觸發(fā),一個是取消,取消自然就是onmouseout,觸發(fā)的話可以傳入?yún)?shù)來制定,使用中括號可以解決這個問題

for(var i=0;i<this.tLen;i++){
    this.triggerItem[i]['on' + this.options.type] = this.change(i)
    this.triggerItem[i].onmouseout = function(){
      clearTime(self.timer);
      self.timer = null;
    }
}
  1. 添加類名和消除類名方法
    實現(xiàn)這種切換效果一般采用的方法都是使用類名的添加和消除來實現(xiàn)的,那么對類名的操作方法就很重要了
addClass:function(el,name){
  var arr = [],
       str = el.className,
       arr = str.split(/\s+/),
       len = arr.length,
       name = this.trim(name),
  for(var i=0;i<len;i++){
    if(arr[i] === name){
      //已存在直接返回
      return;
    }
   }
  el.className += ' ' + name;
  el = null; 
}

消除類名方法類似,主要是用到了一個splice方法。

  1. change選項卡切換函數(shù)
    這個就是給每個導航欄綁定的函數(shù)
    這里也是使用了一個閉包,每次都返回一個新函數(shù)
change:function(index){
  var self = this;
  return function(){
    self.timer = setTimeout(function(){
        for(var i=0;i<self.tLen;i++){
          if(i == index){
            self.addClass(self.triggerItem[index],self.options.curClass);
            self.listItem[i].style.display = 'block';
          }else{
            self.removeClass(self.triggerItem[i],self.options.curClass);
            self.listItem[i].style.display = 'none';
          }
        }
      },self.options.delay)
  }
}

四.總結

其實這個是非常簡單的一個封裝,剛開始學習前端的肯定是都做過這種切換效果的,而這個封裝就是利用對象原型鏈的繼承,來達到一些方法的復用。其中主要的知識點:
1.每新建一個對象都需要init初始化
2.將需要的屬性和方法寫在prototype中
3.利用閉包去給dom綁定事件
4.類名的處理要注意細節(jié),比如檢測是否已存在,是否有空格等
5.對于一些事件要做延遲處理,事件完成后要注意清理現(xiàn)場

五.最后再說兩句

這篇文章實際上沒有什么有價值的內容,但我希望它對我而言是一個學習開始,就像剛剛開始學習前端的時候一樣,那種純粹的技術的渴望。還有幾個月就要畢業(yè)了,才意識到自己的大學真的就這么過去了。就像當時讀大一大二的時候,回家和高中同學聚會也才意識到高中真的就這么過去了,哪怕那個人站在面前,你也感覺和當初的他不同了??蓻]辦法這就是成長。當時還想著要是能重來,一定要好好讀書,一定要追到同桌妹子?,F(xiàn)在大學要過去了,遺憾當然是有,但不會再有那種想重來的想法了,因為哪怕重來也一定差不多,真正重要的是自己心智的變化。不重來照樣可以好好讀書,不重來照樣可以去追求自己喜歡的人,何必把自己限定在一種環(huán)境,一種身份上呢。盡管這段時間以來受刺激很多,心情有點低落,但還是要好好努力,好好生活。就像以前一直以為自己寫文章肯定沒人看的,結果偶爾會有人給你點贊,有人給你回復,也許只是寥寥數(shù)語,但對我而言確實莫大的鼓勵。希望新的一年自己能不斷成長,越來越強大!

源碼地址:https://coding.net/u/ly550275752/p/MyTest/git/blob/coding-pages/tab.js

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,131評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創(chuàng)建,需要時才創(chuàng)建 最常見的單例模式,...
    Obeing閱讀 2,320評論 1 10
  • 深入響應式 追蹤變化: 把普通js對象傳給Vue實例的data選項,Vue將使用Object.defineProp...
    冥冥2017閱讀 4,961評論 6 16
  • 從父親手上接過你的時候 我雙眼泛淚 這是第二次了 我還是無法控制好自己的淚腺 第一次 我哭了 你被逗笑了 今天 我...
    Spancer_Wu閱讀 337評論 0 0
  • 母親,像一只勤勞的蜜蜂,為我們釀蜜,母親,像一頭老黃牛,一直默默無聞的工作,母親像一只春蠶,無私奉獻,母...
    宇淼閱讀 465評論 1 5

友情鏈接更多精彩內容