JavaScript
用我們?cè)趈Query上建置JavaScript插件將Bootstrap生動(dòng)起來。了解每個(gè)插件、數(shù)據(jù)和API以及更多的選項(xiàng)。
單個(gè)插件或集成包
每個(gè)插件都可以被單獨(dú)引入(使用對(duì)應(yīng)每個(gè) Bootstrap 插件的 js/dist/*.js
文件),也可以通過 bootstrap.js
或壓縮版的 bootstrap.min.js
文件一次性引入所有插件(選一個(gè)即可,不要同時(shí)使用)。
如果使用打包程序(Webpack、Rollup 等),你可以使用支持 UMD 格式的 /js/dist/*.js
文件。
將 Bootstrap 作為模塊使用
我們?yōu)?Bootstrap 提供了一個(gè) ESM 模塊(bootstrap.esm.js
和 bootstrap.esm.min.js
)的版本,如果你的目標(biāo)瀏覽器支持的話,你可以在瀏覽器中將 Bootstrap 作為模塊使用。
<script type="module">
import { Toast } from 'bootstrap.esm.min.js'
Array.from(document.querySelectorAll('.toast'))
.forEach(toastNode => new Toast(toastNode))
</script>
不兼容的插件
由于瀏覽器的限制,某些插件,例如下拉菜單(Dropdown)、工具提示(Tooltip)和彈出框(Popover)插件,不能通過設(shè)置為 module
類型的 <script>
標(biāo)簽使用,由于它們都依賴 Popper。有關(guān)此問題的更多信息,請(qǐng)見 這里。
依賴項(xiàng)
某些插件和 CSS 組件依賴于其它插件。如果你選擇單獨(dú)引入某個(gè)插件,請(qǐng)確保在文檔中檢查其是否存在依賴其它插件的情況。
下拉菜單(dropdown)、彈出框(popover)和工具提示(tooltip)組件依賴 Popper。
仍然需要用到j(luò)Query 嗎?有可能!
Bootstrap 5 被設(shè)計(jì)為不依賴 jQuery,但你仍可以將 Bootstrap 的組件與 jQuery 一起使用。如果 Bootstrap 在 window 對(duì)象上檢測(cè)到了 jQuery,它將把所有的 Bootstrap 插件添加到 jQuery 的插件系統(tǒng)中。也就意味著你將來能夠通過 $('[data-bs-toggle="tooltip"]').tooltip()
來調(diào)用工具提示組件(tooltip)。同理,其它組件也類似。
data 屬性
幾乎所有的 Bootstrap 插件都可以通過帶有 data 屬性的 HTML 元素單獨(dú)開啟和配置(我們推薦 JavaScript API 為首選方式)。請(qǐng)確保 僅在單個(gè) HTML 元素上使用一組 data 屬性 (例如,你不能通過同一按鈕觸發(fā)工具提示和模態(tài)框。)
選擇器
Currently to query DOM elements we use the native methods querySelector
and
querySelectorAll
for performance reasons, so you have to use valid selectors.
If you use special selectors, for example: collapse:Example
be sure to escape them.
目前,由于性能的原因,我們使用原生方法 querySelector
和 querySelectorAll
來查詢 DOM 元素,因此你必須使用 合法的選擇器。 如果使用特殊的選擇器,例如collapse:Example
,請(qǐng)確保對(duì)其進(jìn)行轉(zhuǎn)義。
事件
Bootstrap 為大多數(shù)插件的獨(dú)特行為提供了自定義事件。通常,事件的命名以不定式或過去分詞形式出現(xiàn),例如,在事件開始時(shí)觸發(fā)的事件名時(shí)不定式形式的(例如 show
),在事件完成時(shí)觸發(fā)的事件名是過去分詞形式的(例如 shown
)。
所有不定式形式命名的事件都提供 preventDefault()
功能。這就賦予了你在動(dòng)作開始之前將其停止的能力。如果事件處理函數(shù)的返回值是 false,將自動(dòng)調(diào)用 preventDefault()
。
var myModal = document.getElementById('myModal')
myModal.addEventListener('show.bs.modal', function (event) {
if (!data) {
return event.preventDefault() // 停止即將展示的模態(tài)框(modal)
}
})
jQuery 事件
如果 jQuery 存在于 window 對(duì)象上,并且jQuery
元素上沒有設(shè)置 data-bs-no-jquery 屬性,Bootstrap 將認(rèn)為 jQuery 存在。如果檢測(cè)到了 jQuery,Bootstrap 將基于 jQuery 的事件系統(tǒng)觸發(fā)相應(yīng)的事件。因此,如果你想監(jiān)聽 Bootstrap 的事件,就必須使用 jQuery 的方法(例如 .on
, .one
)而不能使用 addEventListener
。
$('#myTab a').on('shown.bs.tab', function () {
// do something...
})
編程式 API
所有構(gòu)造函數(shù)都可以接受對(duì)象類型的參數(shù)或沒有參數(shù)(將以默認(rèn)行為初始化插件):
var myModalEl = document.getElementById('myModal')
var modal = new bootstrap.Modal(myModalEl) // 以默認(rèn)值初始化
var modal = new bootstrap.Modal(myModalEl, { keyboard: false }) // 以對(duì)象參數(shù)初始化
如果你想獲取某個(gè)插件的特定實(shí)例,可以調(diào)用每個(gè)插件都暴露出來的 getInstance
方法。為了直接從元素中獲取插件的實(shí)例對(duì)象,請(qǐng)執(zhí)行以下操作:bootstrap.Popover.getInstance(myPopoverEl)
。
構(gòu)造函數(shù)中的CSS選擇器
您還可以使用CSS選擇器作為第一個(gè)參數(shù),而不是DOM元素來初始化插件。目前,該插件的元素是通過querySelector
方法找到的,因?yàn)槲覀兊牟寮恢С謫蝹€(gè)元素。
var modal = new bootstrap.Modal('#myModal')
var dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')
異步編程和轉(zhuǎn)換
所有編程形式的 API 方法都是 異步的,并在 transition 開始之后、結(jié)束之前返回到調(diào)用者。 。
為了在 transition 完成后執(zhí)行某個(gè)動(dòng)作,你可以監(jiān)聽相應(yīng)的事件。
var myCollapseEl = document.getElementById('#myCollapse')
myCollapseEl.addEventListener('shown.bs.collapse', function (event) {
// 可折疊區(qū)域被展開時(shí),此處的動(dòng)作將被執(zhí)行一次
})
另外,對(duì)正在 transitioning 狀態(tài)的組件調(diào)用的任何方法都將被忽略。
var myCarouselEl = document.getElementById('myCarousel')
var carousel = bootstrap.Carousel.getInstance(myCarouselEl) // 獲取輪播(Carousel)組件的實(shí)例
myCarouselEl.addEventListener('slid.bs.carousel', function (event) {
carousel.to('2') // 當(dāng)滑動(dòng)到幻燈片 1 之后,將立即滑動(dòng)到幻燈片 2
})
carousel.to('1') // 開始滑動(dòng)到幻燈片 1 并返回到回調(diào)者
carousel.to('2') // !! 將會(huì)被忽略,因?yàn)榛瑒?dòng)到幻燈片 1 的轉(zhuǎn)換動(dòng)作還未完成 !!
默認(rèn)設(shè)置
你可以通過修改插件的 Constructor.Default
對(duì)象來更改插件的默認(rèn)設(shè)置:
// 將模態(tài)框(modal)插件的 `keyboard` 的默認(rèn)值修改為 false
bootstrap.Modal.Default.keyboard = false
避免沖突(僅對(duì)你使用 jQuery)
有些時(shí)候需要將 Bootstrap 插件與其它 UI 框架一起使用。在這種情況下,難免發(fā)生命名空間的沖突。如果發(fā)生這種情況,你可以在需要還原的插件上調(diào)用 ..noConflict
函數(shù)。
var bootstrapButton = $.fn.button.noConflict() // 重置 $.fn.button 為先前的值
$.fn.bootstrapBtn = bootstrapButton // 為 $().bootstrapBtn 賦予 Bootstrap 的功能
版本號(hào)
每個(gè) Bootstrap 插件都可以通過其構(gòu)造函數(shù)上的 VERSION
屬性進(jìn)行訪問。例如,以工具提示(tooltip)插件為例:
bootstrap.Tooltip.VERSION // => "5.0.0-beta3"
JavaScript被禁用無反饋
當(dāng)禁用JavaScript時(shí),Bootstrap的插件不會(huì)有特別回饋。若你擔(dān)心此等情況中的使用者體驗(yàn),使用<noscript>
以向你的用戶解釋此情形(以及如何重啟JavaScript的方式)和/或添加你自己定義的回饋。
第三方工具庫
Bootstrap 不對(duì)第三方工具庫提供支持,例如 Prototype 或 jQuery UI。盡管存在 .noConflict
和基于命名空間的事件,但仍可能需要您自行解決兼容性問題。
清理工具
工具提示(tooltip)和彈出框(popover)可以接受 HTML 代碼作為參數(shù),但會(huì)使用 Bootstrap 內(nèi)置的清理程序?qū)?HTML 代碼進(jìn)行清理。
The default allowList
value is the following:
allowList
的默認(rèn)值如下所示:
var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
var DefaultAllowlist = {
// Global attributes allowed on any supplied element below.
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
a: ['target', 'href', 'title', 'rel'],
area: [],
b: [],
br: [],
col: [],
code: [],
div: [],
em: [],
hr: [],
h1: [],
h2: [],
h3: [],
h4: [],
h5: [],
h6: [],
i: [],
img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
li: [],
ol: [],
p: [],
pre: [],
s: [],
small: [],
span: [],
sub: [],
sup: [],
strong: [],
u: [],
ul: []
}
如果要向 allowList
添加新值,則可以執(zhí)行如下操作:
var myDefaultAllowList = bootstrap.Tooltip.Default.allowList
// 添加 table 元素
myDefaultAllowList.table = []
// 添加 td 元素以及 td 元素的 data-bs-option 屬性
myDefaultAllowList.td = ['data-bs-option']
// 你可以添加自定義的正則表達(dá)式來對(duì)屬性進(jìn)行校驗(yàn)。
// 請(qǐng)?zhí)岱肋^于寬松的正則表達(dá)式
var myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)
如果你因?yàn)橄矚g使用專用的工具庫(例如 DOMPurify)并想繞過 Bootstrap 的清理程序,則可以這樣操作:
var yourTooltipEl = document.getElementById('yourTooltip')
var tooltip = new bootstrap.Tooltip(yourTooltipEl, {
sanitizeFn: function (content) {
return DOMPurify.sanitize(content)
}
})