JavaScript
透過我們的可選 JavaScript 外掛讓 Bootstrap 更加生動。了解每個外掛、我們的資料和程式化 API 選項等。
單獨引入或編譯版(Individual or compiled)
外掛可以單獨引入(使用 Bootstrap 的個別 js/dist/*.js),或使用 bootstrap.js 或壓縮版 bootstrap.min.js 一次全部引入(不要同時引入兩者)。
如果您使用打包工具(Webpack、Parcel、Vite...),可以使用已準備好 UMD 的 /js/dist/*.js 檔案。
與 JavaScript 框架搭配使用(Usage with JavaScript frameworks)
雖然 Bootstrap CSS 可以與任何框架搭配使用,但 Bootstrap JavaScript 與 React、Vue 和 Angular 等 JavaScript 框架並不完全相容,因為這些框架假設對 DOM 有完整的控制權。Bootstrap 和框架都可能嘗試變更相同的 DOM 元素,導致下拉選單卡在「開啟」位置等錯誤。
對於使用這類框架的人,更好的替代方案是使用框架專用套件來取代 Bootstrap JavaScript。以下是一些最受歡迎的選項:
- React:React Bootstrap
親自試試! 從 twbs/examples 儲存庫下載使用 Bootstrap 搭配 React、Next.js 和 React Bootstrap 的原始碼和實際範例。您也可以在 StackBlitz 中開啟此範例。
- Vue:BootstrapVue(Bootstrap 4)
- Vue 3:BootstrapVueNext(Bootstrap 5,目前為 alpha 版)
- Angular:ng-bootstrap 或 ngx-bootstrap
以模組方式使用 Bootstrap(Using Bootstrap as a module)
親自試試! 從 twbs/examples 儲存庫下載以 ES 模組方式使用 Bootstrap 的原始碼和實際範例。您也可以在 StackBlitz 中開啟此範例。
我們提供以 ESM 建置的 Bootstrap 版本(bootstrap.esm.js 和 bootstrap.esm.min.js),如果您的目標瀏覽器支援,這允許您在瀏覽器中以模組方式使用 Bootstrap。
<script type="module">
import { Toast } from 'bootstrap.esm.min.js'
Array.from(document.querySelectorAll('.toast'))
.forEach(toastNode => new Toast(toastNode))
</script>
與 JS 打包工具相比,在瀏覽器中使用 ESM 需要您使用完整路徑和檔案名稱,而不是模組名稱。閱讀更多關於瀏覽器中的 JS 模組。 這就是為什麼我們在上面使用 'bootstrap.esm.min.js' 而不是 'bootstrap'。然而,這因為我們的 Popper 相依性而變得更複雜,它像這樣將 Popper 匯入到我們的 JavaScript 中:
import * as Popper from "@popperjs/core"
如果您照原樣嘗試,您會在主控台中看到類似以下的錯誤:
Uncaught TypeError: Failed to resolve module specifier "@popperjs/core". Relative references must start with either "/", "./", or "../".
要修復此問題,您可以使用 importmap 將任意模組名稱解析為完整路徑。如果您的目標瀏覽器不支援 importmap,您需要使用 es-module-shims 專案。以下是 Bootstrap 和 Popper 的運作方式:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<title>Hello, modularity!</title>
</head>
<body>
<h1>Hello, modularity!</h1>
<button id="popoverButton" type="button" class="btn btn-primary btn-lg" data-bs-toggle="popover" title="ESM in Browser" data-bs-content="Bang!">Custom popover</button>
<script async src="https://cdn.jsdelivr.net/npm/es-module-shims@1/dist/es-module-shims.min.js" crossorigin="anonymous"></script>
<script type="importmap">
{
"imports": {
"@popperjs/core": "https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/esm/popper.min.js",
"bootstrap": "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.esm.min.js"
}
}
</script>
<script type="module">
import * as bootstrap from 'bootstrap'
new bootstrap.Popover(document.getElementById('popoverButton'))
</script>
</body>
</html>
相依性(Dependencies)
某些外掛和 CSS 元件依賴其他外掛。如果您單獨引入外掛,請務必在文件中檢查這些相依性。
我們的下拉選單、彈出提示框和工具提示框也依賴 Popper。
Data 屬性(Data attributes)
幾乎所有的 Bootstrap 外掛都可以僅透過 HTML 的 data 屬性來啟用和設定(這是我們偏好的使用 JavaScript 功能的方式)。請確保在單一元素上只使用一組 data 屬性(例如,您不能從同一個按鈕同時觸發工具提示框和互動視窗)。
由於選項可以透過 data 屬性或 JavaScript 傳遞,您可以將選項名稱附加到 data-bs-,例如 data-bs-animation="{value}"。透過 data 屬性傳遞選項時,請確保將選項名稱的大小寫類型從「camelCase」更改為「kebab-case」。例如,使用 data-bs-custom-class="beautifier" 而不是 data-bs-customClass="beautifier"。
從 Bootstrap 5.2.0 開始,所有元件都支援實驗性的保留 data 屬性 data-bs-config,可以將簡單的元件配置作為 JSON 字串存放。當元素同時具有 data-bs-config='{"delay":0, "title":123}' 和 data-bs-title="456" 屬性時,最終的 title 值將是 456,個別的 data 屬性將覆寫 data-bs-config 中給定的值。此外,現有的 data 屬性也能夠存放 JSON 值,例如 data-bs-delay='{"show":0,"hide":150}'。
最終的配置物件是 data-bs-config、data-bs- 和 js object 的合併結果,其中最後給定的鍵值對會覆寫其他的。
選擇器(Selectors)
由於效能原因,我們使用原生的 querySelector 和 querySelectorAll 方法來查詢 DOM 元素,因此您必須使用有效的選擇器。如果您使用特殊選擇器如 collapse:Example,請確保對它們進行跳脫處理。
事件(Events)
Bootstrap 為大多數外掛的獨特操作提供自訂事件。一般來說,這些事件以不定詞和過去分詞形式出現——不定詞(例如 show)在事件開始時觸發,其過去分詞形式(例如 shown)在操作完成時觸發。
所有不定詞事件都提供 preventDefault() 功能。這提供了在操作開始前停止執行的能力。從事件處理常式返回 false 也會自動呼叫 preventDefault()。
const myModal = document.querySelector('#myModal')
myModal.addEventListener('show.bs.modal', event => {
return event.preventDefault() // 阻止互動視窗顯示
})
程式化 API(Programmatic API)
所有建構函式都接受一個可選的選項物件或不傳入任何參數(這會以預設行為初始化外掛):
const myModalEl = document.querySelector('#myModal')
const modal = new bootstrap.Modal(myModalEl) // 以預設值初始化
const configObject = { keyboard: false }
const modal1 = new bootstrap.Modal(myModalEl, configObject) // 初始化時不使用鍵盤
如果您想取得特定外掛實例,每個外掛都公開一個 getInstance 方法。例如,直接從元素取得實例:
bootstrap.Popover.getInstance(myPopoverEl)
如果請求的元素上沒有初始化實例,此方法將返回 null。
或者,可以使用 getOrCreateInstance 來取得與 DOM 元素關聯的實例,如果尚未初始化則建立一個新的。
bootstrap.Popover.getOrCreateInstance(myPopoverEl, configObject)
如果實例尚未初始化,它可以接受並使用可選的設定物件作為第二個參數。
建構函式中的 CSS 選擇器(CSS selectors in constructors)
除了 getInstance 和 getOrCreateInstance 方法外,所有外掛建構函式都可以接受 DOM 元素或有效的 CSS 選擇器作為第一個參數。外掛元素使用 querySelector 方法查找,因為我們的外掛只支援單一元素。
const modal = new bootstrap.Modal('#myModal')
const dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')
const offcanvas = bootstrap.Offcanvas.getInstance('#myOffcanvas')
const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')
非同步函式和轉場(Asynchronous functions and transitions)
所有程式化 API 方法都是非同步的,並在轉場開始後返回給呼叫者,但在轉場結束之前。為了在轉場完成後執行操作,您可以監聽對應的事件。
const myCollapseEl = document.querySelector('#myCollapse')
myCollapseEl.addEventListener('shown.bs.collapse', event => {
// 摺疊區域展開後要執行的操作
})
此外,對正在轉場的元件呼叫方法將被忽略。
const myCarouselEl = document.querySelector('#myCarousel')
const carousel = bootstrap.Carousel.getInstance(myCarouselEl) // 取得輪播實例
myCarouselEl.addEventListener('slid.bs.carousel', event => {
carousel.to('2') // 轉場到投影片 1 完成後會立即滑動到投影片 2
})
carousel.to('1') // 開始滑動到投影片 1 並返回給呼叫者
carousel.to('2') // !! 將被忽略,因為轉場到投影片 1 尚未完成 !!
dispose 方法
雖然在 hide() 之後立即使用 dispose 方法可能看起來是正確的,但這會導致不正確的結果。以下是問題使用的範例:
const myModal = document.querySelector('#myModal')
myModal.hide() // 這是非同步的
myModal.addEventListener('shown.bs.hidden', event => {
myModal.dispose()
})
預設設定(Default settings)
您可以透過修改外掛的 Constructor.Default 物件來變更外掛的預設設定:
// 將互動視窗外掛的 `keyboard` 選項預設值變更為 false
bootstrap.Modal.Default.keyboard = false
方法和屬性(Methods and properties)
每個 Bootstrap 外掛都公開以下方法和靜態屬性。
| 方法 | 說明 |
|---|---|
dispose | 銷毀元素的互動視窗。(移除儲存在 DOM 元素上的資料) |
getInstance | 靜態方法,允許您取得與 DOM 元素關聯的互動視窗實例。 |
getOrCreateInstance | 靜態方法,允許您取得與 DOM 元素關聯的互動視窗實例,如果尚未初始化則建立一個新的。 |
| 靜態屬性 | 說明 |
|---|---|
NAME | 返回外掛名稱。(例如:bootstrap.Tooltip.NAME) |
VERSION | 每個 Bootstrap 外掛的版本可以透過外掛建構函式的 VERSION 屬性存取(例如:bootstrap.Tooltip.VERSION) |
清理器(Sanitizer)
如果設定為這樣做,我們的工具提示框和彈出提示框元件能夠在頁面上渲染任意 HTML。 為了防止跨站腳本(XSS)攻擊,這些元件使用我們內建的內容清理器,在渲染到頁面之前清理任何接受 HTML 的選項。內容清理預設是啟用的。
預設允許的標籤和屬性如下。任何未明確允許的標籤或屬性都將在清理過程中被移除:
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
export const 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: [],
dd: [],
div: [],
dl: [],
dt: [],
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: []
}
使用這些進階選項時請謹慎。 請參閱 OWASP 的跨站腳本預防速查表以獲取更多資訊。僅因停用或修改內容清理而導致的漏洞不被視為 Bootstrap 安全模型的範圍內。
您可以將新值加入到這個預設的 allowList:
const myDefaultAllowList = bootstrap.Tooltip.Default.allowList
// 允許 table 元素
myDefaultAllowList.table = []
// 允許 td 元素和 td 元素上的 data-bs-option 屬性
myDefaultAllowList.td = ['data-bs-option']
// 您可以推送自訂的正規表達式來驗證您的屬性。
// 請注意您的正規表達式不要太寬鬆
const myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)
您也可以用專門的函式庫替換我們的清理器,例如 DOMPurify:
const yourTooltipEl = document.querySelector('#yourTooltip')
const tooltip = new bootstrap.Tooltip(yourTooltipEl, {
sanitizeFn(content) {
return DOMPurify.sanitize(content)
}
})
可選擇使用 jQuery(Optionally using jQuery)
在 Bootstrap 5 中您不需要 jQuery,但仍然可以使用 jQuery 來使用我們的元件。如果 Bootstrap 在 window 物件中偵測到 jQuery,它會將我們所有的元件加入到 jQuery 的外掛系統中。這允許您執行以下操作:
// 以預設設定啟用工具提示框
$('[data-bs-toggle="tooltip"]').tooltip()
// 以指定設定初始化工具提示框
$('[data-bs-toggle="tooltip"]').tooltip({
boundary: 'clippingParents',
customClass: 'myClass'
})
// 觸發 `show` 方法
$('#myTooltip').tooltip('show')
其他元件也是如此。
避免衝突(No conflict)
有時需要將 Bootstrap 外掛與其他 UI 框架一起使用。在這些情況下,命名空間衝突偶爾會發生。如果發生這種情況,您可以在想要還原值的外掛上呼叫 .noConflict。
const bootstrapButton = $.fn.button.noConflict() // 將 $.fn.button 還原為先前指定的值
$.fn.bootstrapBtn = bootstrapButton // 給 $().bootstrapBtn Bootstrap 的功能
Bootstrap 不正式支援第三方 JavaScript 函式庫,如 Prototype 或 jQuery UI。儘管有 .noConflict 和命名空間事件,仍可能存在需要您自己修復的相容性問題。
jQuery 事件(jQuery events)
如果 jQuery 存在於 window 物件中,且 <body> 上沒有設定 data-bs-no-jquery 屬性,Bootstrap 將偵測到 jQuery。如果找到 jQuery,Bootstrap 將透過 jQuery 的事件系統發出事件。因此,如果您想監聽 Bootstrap 的事件,您需要使用 jQuery 方法(.on、.one)而不是 addEventListener。
$('#myTab a').on('shown.bs.tab', () => {
// 執行某些操作...
})
停用 JavaScript(Disabled JavaScript)
當 JavaScript 被停用時,Bootstrap 的外掛沒有特殊的備用方案。如果您關心這種情況下的使用者體驗,請使用 <noscript> 向您的使用者解釋情況(以及如何重新啟用 JavaScript),和/或加入您自己的自訂備用方案。