Bootstrap學習筆記-模態框
簡介
模態框經過了優化,更加靈活,以彈出對話方塊的形式出現,具有最小和最實用的功能集,參考modal。
用法
HTML結構
- div[class=modal[fade]][id]
- div[class=modal-dialog[modal-lg|modal-md|modal-sm]]
- div[class=modal-content]
- div[class=modal-header]
- h1/h2/h3/h4/h5/h6[class=modal-title]
- div[class=modal-body]
- div[class=modal-footer]
- div[class=modal-header]
- div[class=modal-content]
- div[class=modal-dialog[modal-lg|modal-md|modal-sm]]
示例:
<div class ="modal fade" id="myModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">× ;</span>
</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
呼叫模態框
通過 data 屬性或 JavaScript 呼叫模態框外掛,可以根據需要動態展示隱藏的內容。模態框彈出時還會為 元素新增 .modal-open 類,從而覆蓋頁面預設的滾動行為,並且還會自動生成一個 .modal-backdrop 元素用於提供一個可點選的區域,點選此區域就即可關閉模態框。
通過 data 屬性
不需寫 JavaScript 程式碼也可啟用模態框。通過在一個起控制器作用的元素(例如:按鈕)上新增 data-toggle=”modal” 屬性和data-target=”#foo” 屬性,以及 href=”#foo” 屬性,用於指向被控制的模態框。例如:
<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
完整示例參考dynamic-demo.html.
通過 JavaScript 呼叫
需一行 JavaScript 程式碼,即可通過元素的 id myModal 呼叫模態框:$('#myModal').modal(options)
,完整示例參考dynamic-by-javascript-demo.html。modal引數:
- backdrop boolean/’static’ 預設值為true,Includes a modal-backdrop element. Alternatively, specify static for a backdrop which doesn’t close the modal on click.
- keyboard boolean 預設值為true,鍵盤上的 esc 鍵被按下時關閉模態框。
- show boolean 預設值為true,模態框初始化之後就立即顯示出來。
- remote path 預設值為false,如果提供的是 URL,將利用 jQuery 的 load 方法從此 URL 地址載入要展示的內容(只加載一次)並插入 .modal-content 內。如果使用的是 data 屬性 API,還可以利用 href 屬性指定內容來源地址。下面是一個例項:
<a data-toggle="modal" href="remote.html" data-target="#modal">Click me</a>
modal方法的更多使用方式:
- .modal(options): 將頁面中的某塊內容作為模態框啟用, 接受可選引數 object。
- .modal(‘toggle’): 手動開啟或關閉模態框,在模態框顯示或隱藏之前返回到主調函式中(觸發 shown.bs.modal 或 hidden.bs.modal 事件之前)
- .modal(‘show’): 手動開啟模態框, 在模態框顯示之前返回到主調函式中(也就是,在觸發 shown.bs.modal 事件之前)
- .modal(‘hide’): 手動隱藏模態框, 在模態框隱藏之前返回到主調函式中(也就是,在觸發 hidden.bs.modal 事件之前)。
- .modal(‘handleUpdate’): ???
模態框事件
Bootstrap 的模態框類提供了一些事件用於監聽並執行你自己的程式碼,具體如下所示:
- show.bs.modal: show 方法呼叫之後立即觸發該事件。如果是通過點選某個作為觸發器的元素,則此元素可以通過事件的 relatedTarget 屬性進行訪問。
- shown.bs.modal: 此事件在模態框已經顯示出來(並且同時在 CSS 過渡效果完成)之後被觸發。如果是通過點選某個作為觸發器的元素,則此元素可以通過事件的 relatedTarget 屬性進行訪問。
- hide.bs.modal: hide 方法呼叫之後立即觸發該事件。
- hidden.bs.modal: 此事件在模態框被隱藏(並且同時在 CSS 過渡效果完成)之後被觸發。
- loaded.bs.modal: 從遠端的資料來源載入完資料之後觸發該事件。
簡單示例:
$('#myModal').on('hidden.bs.modal', function (e) {
// do something...
})
- 觸發視窗開啟事件
$("#id").modal(...)
=> 執行show.bs.modal
事件繫結的回撥函式=>執行$("#id").modal(...)
之後的程式碼=>如果有設定remote和loaded.bs.modal事件的監聽函式,則執行該函式=>執行shown.bs.moda
l事件繫結的回撥函式 - 觸發視窗關閉事件
$("#id").modal("close")
=>執行hide.bs.moda
l事件繫結的回撥函式=>執行$("#id").modal("close")
之後的程式碼=>執行hidden.bs.moda
l事件繫結的回撥函式
樣式
- 可選尺寸
- div.modal-dialog.modal-lg
- div.modal-dialog.modal-md,預設
- div.modal-dialog.modal-sm
- 動畫
- div.modal.fade
- div.modal
高階配置
- 增強模態框的可訪問性
.modal 新增 role=”dialog” 和 aria-labelledby=”…” 屬性,用於指向模態框的標題欄;為 .modal-dialog 新增 aria-hidden=”true” 屬性。另外,還應該通過 aria-describedby屬性為模態框 .modal 新增描述性資訊。示例如下:
<div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-describedby="this is a modal!">
<div class="modal-dialog" role="document" aria-hidden="true">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
...
</div>
</div>
</div>
</div>
混合組件
使用柵格系統
<div class="modal fade" role="dialog" aria-labelledby="gridSystemModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="gridSystemModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<div class="col-md-2 col-md-offset-4">.col-md-2 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>
<div class="row">
<div class="col-sm-9">
Level 1: .col-sm-9
<div class="row">
<div class="col-xs-8 col-sm-6">
Level 2: .col-xs-8 .col-sm-6
</div>
<div class="col-xs-4 col-sm-6">
Level 2: .col-xs-4 .col-sm-6
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
原始碼分析
CSS原始碼
body
.modal-open {
overflow: hidden;
}
modal
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
display: none;
overflow: hidden;
-webkit-overflow-scrolling: touch;
outline: 0;
}
.modal.fade .modal-dialog {
-webkit-transition: -webkit-transform .3s ease-out;
-o-transition: -o-transform .3s ease-out;
transition: transform .3s ease-out;
-webkit-transform: translate(0, -25%);
-ms-transform: translate(0, -25%);
-o-transform: translate(0, -25%);
transform: translate(0, -25%);
}
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
.modal-open .modal {
overflow-x: hidden;
overflow-y: auto;
}
modal-dialog
.modal-dialog {
position: relative;
width: auto;
margin: 10px;
}
modal-content
.modal-content {
position: relative;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #999;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
outline: 0;
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
}
modal-backdrop
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1040;
background-color: #000;
}
.modal-backdrop.fade {
filter: alpha(opacity=0);
opacity: 0;
}
.modal-backdrop.in {
filter: alpha(opacity=50);
opacity: .5;
}
modal-header
.modal-header {
min-height: 16.42857143px;
padding: 15px;
border-bottom: 1px solid #e5e5e5;
}
.modal-header .close {
margin-top: -2px;
}
modal-title
.modal-title {
margin: 0;
line-height: 1.42857143;
}
modal-body
.modal-body {
position: relative;
padding: 15px;
}
modal-footer
.modal-footer {
padding: 15px;
text-align: right;
border-top: 1px solid #e5e5e5;
}
.modal-footer .btn + .btn {
margin-bottom: 0;
margin-left: 5px;
}
.modal-footer .btn-group .btn + .btn {
margin-left: -1px;
}
.modal-footer .btn-block + .btn-block {
margin-left: 0;
}
.modal-footer:before,
.modal-footer:after {
display: table;
content: " ";
}
.modal-footer:after {
clear: both;
}
響應式
@media (min-width: 768px) {
.modal-dialog {
width: 600px;
margin: 30px auto;
}
.modal-content {
-webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
}
.modal-sm {
width: 300px;
}
}
@media (min-width: 992px) {
.modal-lg {
width: 900px;
}
}
其他
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
Javascript原始碼
略
分析總結
在模態框被開啟的時候,bootstrap做了如下處理:
- 給body元素新增
class=modal-open
,表示模態框開啟 - 給body新增子元素
<div class="modal-backdrop fade in"></div>
,用於遮擋底層的元素,且提供一個可點選的區域,點選此區域就即可關閉模態框。 - 修改.modal元素的display屬性,由none設定為block
- …
問題
模態框的HTML程式碼放置的位置
務必將模態框的 HTML 程式碼放在文件的最高層級內(也就是說,儘量作為 body 標籤的直接子元素),以避免其他元件影響模態框的展現和/或功能,參考例項wrong-multi-modal-demo.html。Due to how HTML5 defines its semantics, the autofocus HTML attribute has no effect in Bootstrap modals. To achieve the same effect, use some custom JavaScript:
$('#myModal').on('shown.bs.modal', function () {
$('#myInput').focus()
})
- 嵌入視訊
在模態框中嵌入 YouTube 視訊需要增加一些額外的 JavaScript 程式碼,用於自動停止重放等功能,這些程式碼並沒有在 Bootstrap 中提供。請參考這份釋出在 Stack Overflow 上的文章。
Todo
- bootstrap是如何通過data屬性開閉模態框的?
- “增強模態框的可訪問性 ”是做什麼用的?
- …