bootstrap外掛學習-bootstrap.modal.js
先從bootstrap.modal.js
的結構看起。
function($){
var Modal = function(){} //構造器
Modal.prototype = function(){} //構造器的原型
function ..(){} //自定義方法
$.fn.modal = function(){} //在jQuery物件上自定方法
$.fn.modal.defaults = {} //設定預設屬性
$.fn.modal.Constructor = Modal //重置構造器名
$(function(){}) //初始化
}(window.jQuery)
其HTML結構
<a class="btn" data-toggle="modal" href="#myModal" >點選觸發對話方塊</a>
<div class="modal" id="myModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>對話方塊標題</h3>
</div>
<div class="modal-body">
<p>對話方塊內容</p>
</div>
<div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal">關閉</a>
<a href="#" class="btn btn-primary" data-dismiss="modal">儲存更新</a>
</div>
</div>
我們開始過一遍外掛原始碼:從初始化開始
$(function () {
/*
* 在所有有data-toggle='modal'屬性的標籤上幫上click事件,一般為a標籤
* /.*(?=#[^\s]+$)/表示如果匹配成功將#之前的資訊刪除
* 對於jQuery物件,比如a標籤有data-xx型別的,在其data方法中都可以顯示
* 將a標籤data-target指向的或是href的錨點指向的元素傳入modal方法裡
* */
$('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
var $this = $(this), href
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
, option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data());
e.preventDefault()
$target.modal(option)
})
})
根據HTML
提供的結構,$target
為a
標籤所指向的彈出框div
的Jquery
物件。另外$this.data()
存在資料,為{toggle:'modal'}
,這個我在註釋中已經解釋。最後執行$target.modal(option)
,我們進入jQuery物件的這個方法。
$.fn.modal = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('modal')
, options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('modal', (data = new Modal(this, options)))//為modal繫結物件
if (typeof option == 'string') data[option]()
else if (options.show) data.show()
})
}
初始化一些引數,在彈出框div
上加入了一個modal
屬性,如果這個modal
屬性不存在,則例項化Modal
構造器。最後執行show
方法,因為此時你已經點選了a
標籤,讓div
顯示。程式碼中有if(typeof option == 'string')data[option]
,表示程式碼支援傳入方法名,執行該方法,在執行show
方法之前,我們先進入Modal
的構造器中看看。
/*
* 構造器,為所有data-dismiss='modal'屬性的標籤繫結原型上的hide方法
* */
var Modal = function ( content, options ) {
this.options = options
this.$element = $(content)
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
}
很簡單,讓帶有data-dismiss='modal'
屬性的標籤的click
事件交給彈出框div
代理,注意這裡的執行的方法。這裡為什麼要$.proxy(this.hide,this)
這樣寫,第一,需要明白此時的this
表示著構造器的例項,代理的事件需要使用到例項的hide
方法,為什麼例項擁有hide
方法,很簡單this
是Modal
的例項,它繼承了Modal
原型的方法。那proxy
方法中的第二個this
,則表示著這個hide
方法的呼叫者,即上下文,可以試想一下,如果我們不修改這個,那執行這個方法時,其裡面的this
是不是指向了呼叫它的a
標籤呢?(注意留意HTML
結構,擁有data-dismiss
屬性的三個a
標籤,其實分別就是彈出框的關閉按鈕等),那原來定義在原型上的hide
方法中的this
的屬性將不能在正常使用。
綜上,例項化,主要就是給彈出框繫結了hide
事件,為將來關閉彈出框,做準備。
好,回到之前JQuery的modal
方法上,最後我們執行了show
方法,進入show
方法。
下面是執行的流程圖,就是各個方法的執行順序
show -> escape -> backdrop
hide ->escape -> hideModal -> backdrop
show
, show: function () {
var that = this
if (this.isShown) return
$('body').addClass('modal-open')//給body加上modal-open類
this.isShown = true//將isShown屬性設定成true
this.$element.trigger('show');//沒理解
escape.call(this)//加上鍵盤事件
backdrop.call(this, function () {
var transition = $.support.transition && that.$element.hasClass('fade')
//console.log(that.$element);
/*
* 插入彈出層
* */
!that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
that.$element
.show()//jQuery方法顯示
if (transition) {
that.$element[0].offsetWidth // force reflow
}
that.$element.addClass('in')
transition ?
that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
that.$element.trigger('shown')
})
}
談到show
和hide
的時候,我們需要留意它們原始碼中的一些我們認為的’廢’操作,其實它能幫助我們實現擴充套件。比如給body
加modal-open
這個類,如果你要在開啟彈出層,執行其他程式,可以通過判斷這個類來實現,這是bootstrap
它自身已經提供的標識。escape()
方法是一個新增鍵盤事件和刪除鍵盤事件的方法,它可以讓你按enter
鍵也能關閉彈出框,比較簡單。
接下來我們進入backdrop
方法
/*
* 生成遮罩層,並且控制遮罩層的顯示或刪除
* */
function backdrop( callback ) {
var that = this
, animate = this.$element.hasClass('fade') ? 'fade' : ''
if (this.isShown && this.options.backdrop) {
var doAnimate = $.support.transition && animate
//console.log(doAnimate);
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.appendTo(document.body)//遮罩層,讓彈出框顯示時,背景被遮罩,此時為透明的
if (this.options.backdrop != 'static') {
this.$backdrop.click($.proxy(this.hide, this))
}
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
this.$backdrop.addClass('in')//加入in類,顯示遮罩層
doAnimate ?
this.$backdrop.one($.support.transition.end, callback) :
callback()
//開啟時,執行callback()回撥
} else if (!this.isShown && this.$backdrop) {
this.$backdrop.removeClass('in')//刪除in,遮罩層透明
$.support.transition && this.$element.hasClass('fade')?
this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
removeBackdrop.call(this)
//一般執行removeBackdrop()函式
} else if (callback) {
callback()
}
}
這裡為什麼要判斷彈出框是否有fade
類,在bootstrap.css
中,.fade
擁有left:-25%
的屬性,當.fade .in
時則left
變為10%
,在版本較高的瀏覽器中,有自上向下的移動的效果(低版本瀏覽器沒有效果,不過這個可以jQuery實現…),這個部分需要我們結合css
樣式看,注意in的樣式,就可以了,彈出框顯示的最後一步,執行callback
回撥,顯示彈出框,並給彈出框加上in
類,80%
透明度。最後完成顯示。
之前因為我們已經在彈出框的三個a
標籤上都繫結了hide
事件,所以當我們點選關閉時,執行hide
方法
hide: function ( e ) {
e && e.preventDefault()
if (!this.isShown) return
var that = this
this.isShown = false
$('body').removeClass('modal-open')
escape.call(this)//關閉按鍵事件
this.$element
.trigger('hide')
.removeClass('in')//jQuery方法,將彈出框隱藏,並將div的class去in
$.support.transition && this.$element.hasClass('fade') ?
hideWithTransition.call(this) :
hideModal.call(this)
}
其實跟show
方法差不多,主要是給show
擦屁股,進入hideModal
方法
function hideModal( that ) {
this.$element
.hide() //刪除效果更好
.trigger('hidden')
backdrop.call(this)
}
蠻蛋疼的方法,還是呼叫backdrop
。最後刪除時我們呼叫的是removeBackdrop
方法。
/*
* 清除遮罩層
* */
function removeBackdrop() {
this.$backdrop.remove()
this.$backdrop = null
}
將之前建立的遮罩層刪除。以上完成一遍彈出框的開啟顯示。
內容不多,時間剛好,以上是我的一點讀碼體會,如有錯誤,請指出,大家共通學習。
相關文章
- Bootstrap外掛modal原始碼的學習boot原始碼
- 前端外掛之Bootstrap Dual Listbox使用前端boot
- 利用Bootstrap Paginator外掛和knockout.jsbootJS
- 淺談bootstrap表單驗證外掛BootstrapValidatorboot
- Gradle外掛學習筆記(一)Gradle筆記
- Gradle外掛學習筆記(四)Gradle筆記
- Cordova學習--iOS自定義外掛iOS
- 【django學習-24】自定義外掛Django
- octobercms 外掛學習 驗證碼
- OctoberCMS 外掛學習 側邊欄
- 前端學習之Bootstrap學習前端boot
- Flutter學習指南:封裝 API 外掛Flutter封裝API
- Egg 學習筆記 - 外掛的使用筆記
- 學習bootstrap的整理。boot
- Bootstrap4動態模態視窗jquery外掛bootjQuery
- 基於Bootstrap的Material Design風格表單外掛bootMaterial Design
- 基於Bootstrap的jQuery使用者嚮導外掛bootjQuery
- Bootstrap框架:學習筆記boot框架筆記
- bootstrap導航欄學習boot
- 基於Bootstrap的強大jQuery表單驗證外掛bootjQuery
- Flutter外掛學習之Native通訊詳解Flutter
- less學習之Bootstrap(按鈕篇)boot
- Bootstrap 個人學習知識點boot
- jquery複習之路---常用外掛jQuery
- 基於jquery的外掛turn.js學習筆記jQueryJS筆記
- Vue3學習(二十)- 富文字外掛wangeditor的使用Vue
- openstack neutron網路外掛學習(三)【Open vSwitch實現】
- Flutter學習(9)——Flutter外掛實現(Flutter呼叫Android原生FlutterAndroid
- jQuery+bootstrap實現美化警告/確認/提示對話方塊外掛jQueryboot
- Bootstrap柵格系統學習總結boot
- Vue & Bootstrap 結合學習筆記(二)Vueboot筆記
- Vue & Bootstrap 結合學習筆記(一)Vueboot筆記
- 從bootstrap原始碼中學習Sass(一)boot原始碼
- [Bootstrap 5 學習記錄](一)搭建框架boot框架
- 【Bootstrap5】精細學習記錄boot
- 前端學習-UI框架學習-Bootstrap5-010-按鈕組前端UI框架boot
- 前端學習-UI框架學習-Bootstrap5-012-進度條前端UI框架boot
- 深度學習“吃雞外掛”——目標檢測 SSD 實驗深度學習