山寨HTML5API classList類

來源:互聯網
上載者:User

preface

覺得自己去寫一些類,你真的會找到自己不足的地方。其實厲害不是你實現一個類,而是你如何去設計一個類,能讓開發人員更加容易操作。對於這個操作樣式,可以通過javascript訪問style,可是在《javascript進階程式設計》中有講到這樣子CSS、javascript、HTML耦合度太高,不太適合維護;還有就是通過className,但是我們知道className是一個可以被開發人員讀寫的字串,如果要增刪查改元素對應的className的話,可以實現,但是比較麻煩。這個時候HTML5站出來了,提出了classList類,確實方便我們開發人員去使用,但是它有一個弊端就是相容性不是很好。

introduction
簡單介紹element.classList,下面是它的4個方法
1 add a class to an element's list of classes(為元素添加class)
2 remove a class from an element's list of classes(刪除元素的class)
3 toggle the existence of a class in an element's list of classes ◦See below about the optional     second argument.(切換元素的class)
4 check if an element's list of classes contains a specific class(檢查元素是否有這個class)

確實覺得這樣的API讓開發人員少做很多苦力活,詳細的可以去看element.classList,畢竟上面不是我想深入瞭解的知識點,我想深入瞭解的是,自己先去模仿別人設計的API,看自己能不能擴充那個API(很顯然自己還沒達到那種程度)。

description

在這裡說明下我定義的CSSClassList可以到我《javascriptRegex "\b"問題》找,這裡我就不詳述了。我們主要還是來實現上面說的4個方法,可以在不支援classListAPI的瀏覽器上用

一 contains方法(個人覺得這個方法是最重要的,之後的add remove和toggle方法都要用到)

CSSClassList.prototype.contains = function(cls) {

var classname = this.el.className, reg = new RegExp("\\b" + cls + "\\b");

return reg.test(classname);

}

遇見的問題:

  • 1 在《javascriptRegex "\b"問題》其實有提到一個比較容易忽略的問題就是對於字串"\b"與"\\b"的區別。
  • 2 如何將一個字串轉換成Regex

解決問題(1就是對應上面的問題1,以此類推)

  • 1 在《javascriptRegex "\b"問題》有說道,這裡不再詳述。
  • 2 在我腦海中現在有兩種方法,一種是用eval,但是因為安全性還有效能問題被我否決了,所以我改成了第二種方法是用RegExp建構函式。如果對於現在正在讀我的blog的您來說,有更好的方法請告訴我,大家來交流交流。
二 add方法

CSSClassList.prototype.add = function(cls) {

var classname = this.el.className;

if (this.contains(cls))

return;

else {

var arr = classname.split(/\s+/);

arr.push(cls);

this.el.className = arr.join(" ");

}}

設計思路: 

     如果在該元素中找到class的話,就不添加了。找不到就添加,如何去添加?我把該元素的className字元      串轉成數組,然後使用數組的push方法並把數群組轉換成字串賦值給該元素的className

遇見的問題:

  • 對於字串的split方法不是很熟練,比如上面有句代碼我寫成了var arr = classname.split("/\s+/");記住在split參數中是Regex但是我又畫蛇添足加了雙引號""。

解決問題:

  • String.prototype.split()
三 remove方法(這個方法還是我折騰比較久的)

CSSClassList.prototype.remove = function(cls) {

var classname = this.el.className;

if (!this.contains(cls))

return -1;

else {

//indexOf還是有相容性問題

var arr = classname.split(/\s+/), index = arrIndexOf(arr, cls);

arr.splice(index, 1);

this.el.className = arr.join(" ");

return (this.el.className);

}

}
設計思路:找不到要刪除的class就返回-1,然後確定該元素有這個class,就要去找那個class是在哪,然後把它刪除掉。還是那樣子先把該元素的className轉換成數組,然後可以用到ES5的Array.prototype.indexOf方法找到class對應的下標,但是被我否決了,因為這個indexOf只能在IE9+才能用,如過IE9+能用的話,其實就沒必要去實現山寨的classList,因為IE9+本身就支援,那怎麼辦?下面會詳述。找到對應的下標就用數組的splice去刪除該class並把刪除後的數群組轉換成字串賦給該元素的className

遇到問題

  • 主要還是怎麼用原生的javascript去實現indexOf方法?

解決問題

  • function arrIndexOf(arr, searchEl) {

    if (arr.indexOf) {

      return arr.indexOf(searchEl);

     } else {

      for (var i = 0, len = arr.length; i < len; i++) {

        if (arr[i] === searchEl)

          return i;

     }

      return -1;

     }

    }

就不用我過多去解釋了吧,應該看完代碼很容易懂吧,我也不是什麼大牛級,所以我寫的代碼還是很平易近人的。
四 toggle方法

CSSClassList.prototype.toggle = function(cls) {

if (!this.contains(cls))

  this.add(cls);

else

  this.remove(cls);

}

這個就不說了,一看就知道了。
summary

在寫這個類的時候確實還是遇到很多問題,但是總是能一一解決。我覺得一個程式員最重要的是他的解決問題的能力吧。畢竟自己寫的類也不是很多,可能是自己的處女作吧,還是會有許多問題出現的,有空的話,我會看看其他大牛寫的代碼,然後兩者再比較,有對比才有差距才有進步。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.