bootstrap插件學習-bootstrap.dropdown.js


先看bootstrap.dropdown.js的結構

var toggle = '[data-toggle="dropdown"]'//屬性標記
Dropdown = function(){} //構造器
Dropdown.prototype = {} // 構造器的原型
function clearMenus() // 自定義方法
$.fn.dropdown = function ( option ){}//jQuery原型上的自定義方法
$.fn.dropdown.Constructor = Dropdown //重寫方法的構造函數名
$(function(){}) //默認初始化執行

HTML結構

<ul class="nav nav-pills">
      <li><a href="#">規則的鏈接</a></li>
      <li class="dropdown" id="menutest1">
        <a class="dropdown-toggle" data-toggle="dropdown" href="#menutest1">
          下拉項
          <b class="caret"></b>
        </a>
        <ul class="dropdown-menu">
          <li><a href="#">動作</a></li>
          <li><a href="#">另一個動作</a></li>
          <li><a href="#">其他</a></li>
          <li class="divider"></li>
          <li><a href="#">被間隔的鏈接</a></li>
        </ul>
      </li>
      <li class='active'>
        <a data-toggle="dropdown" href="#menutest1">點擊我看看</a>
      </li>
    </ul>

 從初始化即時函數開始

/*
  * 默認初始化執行
  * 初始化時,給html和body分別加入監聽事件click,html這觸發clearMenus方法,body則讓toggle對象觸發Dropdown原型上的方法
  * */
  $(function () {
    $('html').on('click.dropdown.data-api', clearMenus)
    $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
  })

這里需要注意事件的冒泡,一般我們點擊頁面上的一個按鈕(或者一個可見的標簽時)時,現在你點擊的這個標簽上先觸發事件,如果你這個標簽上有事件的話,觸發完之后,它會繼續向上冒泡,到其父節點,看是否有綁定事件,接着依次向上冒泡,直到文檔節點,拿上面的代碼講,我們如果點擊了頁面中的按鈕,先是body上的事件觸發,然后則是html上的事件觸發。

我們先從body的事件開始,body的監聽事件綁定到擁有data-toggle='dropdown'屬性的標簽上,根據HTML的結構,我們可以清楚的看到有兩個標簽擁有事件,下面進入該事件Dropdown原型上的toggle方法

//構造器的原型
  Dropdown.prototype = {

    constructor: Dropdown

  , toggle: function ( e ) {
      var $this = $(this)
        , selector = $this.attr('data-target')
        , $parent
        , isActive;
      /*
      * 如果沒有data-target屬性,則使用a標簽的href屬性,根據正則取到其#和#以后的字符串,放入jQuery容器中,
      * 變為jQuery對象。
      * */
      if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
      }

      $parent = $(selector)
      //console.log($parent);
//如果沒寫,則自動去獲取其父節點
$parent.length || ($parent = $this.parent()) isActive = $parent.hasClass('open') clearMenus() /* * 如果li標簽上沒有open類則加上open類 * */ !isActive && $parent.toggleClass('open') return false//阻止冒泡 } }

這里,方法先判斷點擊標簽是否擁有data-target屬性,如果沒有則需要正則去解析href,兩種方法的目的就是為了得到與這個標簽相關聯控制下拉框的li,為什么不直接找到下拉框信息的ul,原因在bootstrap.css里,在此之前,我們先進入clearMenus方法看一下。

  //自定義方法
    /*
    * 根據HTML結構,我們舉例,$(toggle)為a標簽的jQuery對象,
    * */
  function clearMenus() {
    $(toggle).parent().removeClass('open')//如果點擊文檔,則執行將li標簽去除open類,其實這個open類也是個標記,我們可以利用,便於擴展
  }

清除兩個按鈕的父節點的open類,這里的邏輯是這樣的。

如果頁面有兩個按鈕控制下拉框顯示和隱藏,先判斷我們所點的按鈕的父節點是否有open屬性,然后清空所有按鈕的父節點屬性,然后在給所點按鈕的父節點加上open屬性。至於為啥呢么加上open就能達到效果,看bootstrap.css

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: none;/*dropdown-menu開始為隱藏的*/
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  list-style: none;
  background-color: #ffffff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  *border-right-width: 2px;
  *border-bottom-width: 2px;
  -webkit-border-radius: 6px;
     -moz-border-radius: 6px;
          border-radius: 6px;
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
     -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  -webkit-background-clip: padding-box;
     -moz-background-clip: padding;
          background-clip: padding-box;
}

.open {
  *z-index: 1000;
}

.open > .dropdown-menu {
  display: block;/*加入open類,之后變為顯示*/
}

這種根據css規則去渲染頁面,而不通過js查詢style屬性修改css樣式,感覺前者的效率會更高一些。在bootstrap插件中,很多情況都是采用這種方式,到時候看到我們還需要留意。

之后,你可以選擇點擊本身按鈕(或者是其他按鈕)關閉,或者點擊文檔關閉,都是可以的。兩種方法本身都是執行了clearMenus方法。清除了open屬性。

內容不多,時間剛好,以上是我的一點讀碼體會,如有錯誤,請指出,大家共通學習。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM