跳至主要內容 跳至文件導覽

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。以下是一些最受歡迎的選項:

以模組方式使用 Bootstrap(Using Bootstrap as a module)

親自試試!twbs/examples 儲存庫下載以 ES 模組方式使用 Bootstrap 的原始碼和實際範例。您也可以在 StackBlitz 中開啟此範例

我們提供以 ESM 建置的 Bootstrap 版本(bootstrap.esm.jsbootstrap.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-configdata-bs-js object 的合併結果,其中最後給定的鍵值對會覆寫其他的。

選擇器(Selectors)

由於效能原因,我們使用原生的 querySelectorquerySelectorAll 方法來查詢 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)

除了 getInstancegetOrCreateInstance 方法外,所有外掛建構函式都可以接受 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),和/或加入您自己的自訂備用方案。