估計大概兩三個月沒有這類的關於前端的文章了,一來是以爲本身太菜,二來也是由於本身的懶散,渾渾噩噩的消耗時間卻沒有收穫什麼成果。今天由於和一些同窗的聊天,忽然本身的心情很低落,有一種看不到將來在哪的感受,因此強行讓本身學習,去看js插件怎麼寫。今天寫一個簡單的選項卡插件,這個我也是看別人博文學習實現的,而後加一些本身的理解。html
雖然說有點簡陋,可是能夠看到在html文件中,引入咱們寫的tab.js插件後,實現選項卡切換,就只需一行代碼就能夠實現了。前端
先總體看下結構大概是怎樣git
//一開始固然是建立一個構造函數tab function Tab(){ //裏面只有一行代碼,就是調用自身的初始化方法 this.init.apply(this,arguments); } //須要的屬性和方法所有寫在prototype裏面 Tab.prototype = { //屬性 //some code //方法 //some code }
咱們在這裏沒有使用閉包而後當即執行,因此才須要一個初始化函數將屬性都初始化,在init中:閉包
init:function(ela,elb,paramObj){ //通常在插件中都會有個配置對象,而且有默認值 this.defaultOptions = { curClass:'current', type:'mouseover', delay:150 } //而後咱們會去檢測用戶有沒有傳入配置參數,有的話就要使用用戶的配置,這裏使用到一個extend方法 this.options = this.extend(this.defaultOptions, paramObj || {}) }
extend實際是一個對象拓展方法,將b對象的屬性覆蓋到a對象中,在JQ裏直接寫好了這種方法,但js裏沒有,須要咱們本身去模擬,咱們將這個方法寫在init外面app
extend:function(a,b){ for(var i in b){ //這個是檢測for循環到的屬性是否是b自身的 if(b.hasOwnProperty(i)){ a[i] = b[i] } } return a; }
後面init裏就是一些基本的屬性,好比獲取導航欄的DOM,內容塊的DOM,以及他們的子元素還有子元素的個數,後面遍歷會用到,具體可在文章附的源碼裏去看。最後咱們要在init中給每一個導航綁定事件,一個是觸發,一個是取消,取消天然就是onmouseout,觸發的話能夠傳入參數來制定,使用中括號能夠解決這個問題dom
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; } }
添加類名和消除類名方法
實現這種切換效果通常採用的方法都是使用類名的添加和消除來實現的,那麼對類名的操做方法就很重要了函數
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方法。學習
change選項卡切換函數
這個就是給每一個導航欄綁定的函數this
這裏也是使用了一個閉包,每次都返回一個新函數spa
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.類名的處理要注意細節,好比檢測是否已存在,是否有空格等
5.對於一些事件要作延遲處理,事件完成後要注意清理現場
這篇文章實際上沒有什麼有價值的內容,但我但願它對我而言是一個學習開始,就像剛剛開始學習前端的時候同樣,那種純粹的技術的渴望。還有幾個月就要畢業了,才意識到本身的大學真的就這麼過去了。就像當時讀大一大二的時候,回家和高中同窗聚會也才意識到高中真的就這麼過去了,哪怕那我的站在面前,你也感受和當初的他不一樣了。可沒辦法這就是成長。當時還想着要是能重來,必定要好好讀書,必定要追到同桌妹子。如今大學要過去了,遺憾固然是有,但不會再有那種想重來的想法了,由於哪怕重來也必定差很少,真正重要的是本身心智的變化。不重來照樣能夠好好讀書,不重來照樣能夠去追求本身喜歡的人,何須把本身限定在一種環境,一種身份上呢。儘管這段時間以來受刺激不少,心情有點低落,但仍是要好好努力,好好生活。就像之前一直覺得本身寫文章確定沒人看的,結果偶爾會有人給你點贊,有人給你回覆,也許只是寥寥數語,但對我而言確實莫大的鼓勵。但願新的一年本身能不斷成長,愈來愈強大!