先看bootstrap.dropdown.js的結構css
var toggle = '[data-toggle="dropdown"]'//屬性標記 Dropdown = function(){} //構造器 Dropdown.prototype = {} // 構造器的原型 function clearMenus() // 自定義方法 $.fn.dropdown = function ( option ){}//jQuery原型上的自定義方法 $.fn.dropdown.Constructor = Dropdown //重寫方法的構造函數名 $(function(){}) //默認初始化執行
HTML結構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>
從初始化即時函數開始web
/* * 默認初始化執行 * 初始化時,給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上的事件觸發。bootstrap
咱們先從body的事件開始,body的監聽事件綁定到擁有data-toggle='dropdown'屬性的標籤上,根據HTML的結構,咱們能夠清楚的看到有兩個標籤擁有事件,下面進入該事件Dropdown原型上的toggle方法api
//構造器的原型 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方法看一下。ide
//自定義方法 /* * 根據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插件中,不少狀況都是採用這種方式,到時候看到咱們還須要留意。this
以後,你能夠選擇點擊自己按鈕(或者是其餘按鈕)關閉,或者點擊文檔關閉,都是能夠的。兩種方法自己都是執行了clearMenus方法。清除了open屬性。spa
內容很少,時間恰好,以上是個人一點讀碼體會,若有錯誤,請指出,你們共通學習。