跳到主要内容
输入关键词开始搜索,↑ ↓ 选择,Enter 打开
没有找到匹配的文档

JavaScript

通过我们的可选 JavaScript 插件让 Bootstrap 生动起来。了解每个插件、我们的数据和编程 API 选项,以及更多内容。

JS 组件

好奇哪些组件明确需要我们的 JavaScript 和 Floating UI 或 Vanilla Calendar Pro?

  • 解散的警报
  • 用于切换状态和复选框/单选按钮功能的按钮
  • 适用于所有幻灯片行为、控件和指示器的轮播
  • 折叠以切换内容的可见性
  • 用于日期选择的日期选择器(也需要 Vanilla Calendar Pro)
  • 对话 用于显示、定位和滚动行为
  • 用于显示和定位的菜单(也需要 浮动界面)
  • 用于扩展我们的 Collapse 和 Drawer 插件以实现响应式行为的导航栏
  • 导航 用于导航标记和样式; 标签 用于切换标签窗格的插件
  • 用于显示、定位和滚动行为的抽屉
  • 用于滚动行为和导航更新的滚动监听
  • 用于显示和消失的提示
  • 用于显示和定位的工具提示和弹出框(也需要 Floating UI)

个人或编译

插件可以单独包含(使用 Bootstrap 的单独 js/dist/*.js),或者使用 bootstrap.js 或压缩的 bootstrap.min.js 一次性全部包含(不要同时包含两者)。

如果你使用打包工具(Webpack、Parcel、Vite…),你可以只导入你需要的插件,你的打包工具会自动去除其余部分:

JavaScript
          import { Toast, Tooltip } from 'bootstrap'
        

TypeScript

Bootstrap 的插件是用 TypeScript 编写的,并附带内置类型声明——不需要 @types/bootstrap 包。主入口点以及 js/dist/*.js 下的每个单独插件都是完全类型化的,包括每个插件的配置选项:

TypeScript
          import { Tooltip } from 'bootstrap'

const tooltip = Tooltip.getOrCreateInstance('#example')
tooltip.show()
        

每个插件模块也会导出其配置对象类型(例如 TooltipConfig),如果你需要为自己的包装器进行类型定义。

与 JavaScript 框架的使用

虽然 Bootstrap CSS 可以与任何框架一起使用,但 Bootstrap JavaScript 并不完全兼容像 React、Vue 和 Angular 这样的 JavaScript 框架,这些框架假设对 DOM 有完全的了解。Bootstrap 和框架都可能尝试修改同一个 DOM 元素,从而导致菜单卡在“打开”状态等错误。

对于使用这种类型框架的人来说,更好的选择是使用特定于框架的包 而不是 Bootstrap 的 JavaScript。以下是一些最受欢迎的选项:

将 Bootstrap 作为模块使用

自己试一试! 从 twbs/examples 仓库 下载使用 Bootstrap 作为 ES 模块的源代码和工作演示。

Bootstrap 的 JavaScript 是作为原生 ES 模块构建的(bootstrap.js 和 bootstrap.min.js)。使用 <script type="module"> 在浏览器中加载 Bootstrap:

HTML
          <script type="module">
  import { Toast } from './bootstrap.min.js'

  Array.from(document.querySelectorAll('.toast'))
    .forEach(toastNode => new Toast(toastNode))
</script>
        

在浏览器中使用 ESM 需要完整路径或一个 导入地图 对于像这样的裸模块说明符 @floating-ui/dom 和 vanilla-calendar-pro这是一个使用导入映射的完整示例:

HTML
          <!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/bootstrap@6.0.0-alpha.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-B/GM4XqrwHnWXNOWMbloTmrYXZg10cakYGmpfsR/bbzQ6JAJI4ihuyADKLnBgrCe" crossorigin="anonymous">
    <title>Hello, modularity!</title>
  </head>
  <body>
    <h1>Hello, modularity!</h1>
    <button id="popoverButton" type="button" class="btn-solid theme-primary btn-lg" data-bs-toggle="popover" title="ESM in Browser" data-bs-content="Bang!">Custom popover</button>

    <script type="importmap">
    {
      "imports": {
        "@floating-ui/dom": "https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.6/dist/floating-ui.dom.esm.min.js",
        "vanilla-calendar-pro": "https://cdn.jsdelivr.net/npm/vanilla-calendar-pro@3.4.0/index.mjs",
        "bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@6.0.0-alpha.1/dist/js/bootstrap.min.js"
      }
    }
    </script>
    <script type="module">
      import * as bootstrap from 'bootstrap'

      new bootstrap.Popover(document.getElementById('popoverButton'))
    </script>
  </body>
</html>
        

不依赖 Floating UI 的组件(如 Toast、Alert、Collapse 等)可以单独导入,无需任何导入映射:

HTML
          <script type="module">
  import Toast from './js/dist/toast.js'

  Array.from(document.querySelectorAll('.toast'))
    .forEach(toastNode => new Toast(toastNode))
</script>
        

依赖

一些插件和 CSS 组件依赖于其他插件。如果你单独包含插件,请确保在文档中检查这些依赖关系。

我们的菜单、弹出层和工具提示也依赖于 Floating UI。我们的日期选择器也依赖于 Vanilla Calendar Pro。

数据属性

几乎所有的 Bootstrap 插件都可以仅通过 HTML 使用数据属性启用和配置(这是我们首选的使用 JavaScript 功能的方式)。请确保 在单个元素上只使用一组数据属性(例如,不能通过同一个按钮触发工具提示和对话框)。

由于选项可以通过数据属性或 JavaScript 传递,你可以将选项名称附加到 data-bs-,就像在 data-bs-animation="{value}" 中一样。确保在通过数据属性传递选项时,将选项名称的大小写类型从“camelCase”更改为“kebab-case”。例如,使用 data-bs-custom-class="beautifier" 而不是 data-bs-customClass="beautifier"。

所有组件都支持一个保留的数据属性 data-bs-config,该属性可以以 JSON 字符串的形式存放简单的组件配置。当一个元素具有 data-bs-config='{"delay":0, "title":123}' 和 data-bs-title="456" 属性时,最终的 title 值将是 456,并且单独的数据属性将覆盖在 data-bs-config 上给定的值。此外,现有的数据属性也可以存放像 data-bs-delay='{"show":0,"hide":150}' 这样的 JSON 值。

最终的配置对象是data-bs-config、data-bs-和js object合并的结果,其中最新提供的键值会覆盖其他键值。

选择器

出于性能原因,我们使用原生的 querySelector 和 querySelectorAll 方法查询 DOM 元素,因此你必须使用有效选择器。如果你使用像 collapse:Example 这样的特殊选择器,请确保对它们进行转义。

事件

Bootstrap 为大多数插件的独特操作提供自定义事件。通常,这些事件有不定式和过去分词形式 —— 不定式(例如 show)在事件开始时触发,而过去分词形式(例如 shown)在操作完成时触发。

所有不定事件都提供 preventDefault() 功能。这提供了在动作开始之前停止其执行的能力。从事件处理程序中返回 false 也会自动调用 preventDefault()。

JavaScript
          const myDialogEl = document.querySelector('#myDialog')

myDialogEl.addEventListener('show.bs.dialog', event => {
  return event.preventDefault() // stops dialog from being shown
})
        

编程 API

所有构造函数都接受一个可选的 options 对象或不传参数(此时插件将以其默认行为初始化):

JavaScript
          const myDialogEl = document.querySelector('#myDialog')
const dialog = new bootstrap.Dialog(myDialogEl) // initialized with defaults

const configObject = { keyboard: false }
const dialog1 = new bootstrap.Dialog(myDialogEl, configObject) // initialized with no keyboard
        

如果你想获取一个特定的插件实例,每个插件都会提供一个 getInstance 方法。例如,直接从一个元素中检索实例:

JavaScript
          bootstrap.Popover.getInstance(myPopoverEl)
        

如果实例未在请求的元素上初始化,则此方法将返回null。

或者,可以使用 getOrCreateInstance 来获取与 DOM 元素关联的实例,或者在尚未初始化的情况下创建一个新的实例。

JavaScript
          bootstrap.Popover.getOrCreateInstance(myPopoverEl, configObject)
        

如果实例未被初始化,它可能会接受并使用作为第二个参数的可选配置对象。

构造函数中的 CSS 选择器

除了getInstance和getOrCreateInstance方法外,所有插件构造函数都可以接受一个 DOM 元素或一个有效的CSS 选择器作为第一个参数。插件元素通过querySelector方法找到,因为我们的插件只支持单个元素。

JavaScript
          const dialog = new bootstrap.Dialog('#myDialog')
const menu = new bootstrap.Menu('[data-bs-toggle="menu"]')
const drawer = bootstrap.Drawer.getInstance('#myDrawer')
const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')
        

承诺与过渡

所有编程 API 方法都是 异步 的,并在转换开始后 但在其结束之前 返回给调用者。

显示或隐藏组件的方法会返回一个 promise。当过渡结束时,promise 会被解决,所以你可以 await 该方法,而不是监听事件。

JavaScript
          const collapse = bootstrap.Collapse.getOrCreateInstance('#myCollapse')

await collapse.show()
// The collapsible area is now expanded
        

这些方法返回一个 promise:

方法组件
show, hide, toggle折叠面板, 下拉组合框, 日期选择器, 对话框, 抽屉, 菜单, 弹出框, 提示工具
show, hide消息提示
show标签页
close警告

该 Promise 以无值方式完成。它在匹配的 shown.bs.*、hidden.bs.* 或 closed.bs.* 事件触发的同一时刻完成,因此两种方式都会同时运行你的代码。当你必须响应每一次变化,包括那些你的代码没有引发的变化时,请使用该事件。

JavaScript
          const myDrawerEl = document.querySelector('#myDrawer')
const drawer = bootstrap.Drawer.getOrCreateInstance(myDrawerEl)

// Await the method you called…
await drawer.hide()
saveState()

// …or listen for every hide, whoever started it
myDrawerEl.addEventListener('hidden.bs.drawer', () => {
  saveState()
})
        

因为每个方法都会返回一个 promise,你可以按顺序运行步骤,而无需嵌套监听器。

JavaScript
          const dialog = bootstrap.Dialog.getOrCreateInstance('#myDialog')
const toast = bootstrap.Toast.getOrCreateInstance('#myToast')

await dialog.hide()
await toast.show()
        

当调用什么也不做时——例如当组件已经打开,或当监听器调用时——这个承诺也会被解决 preventDefault() 在……上 show.bs.* 事件,或当你在过渡过程中销毁组件时。 await 因此它永远不会挂起,但它也不会告诉你状态是否发生了变化。当状态重要时,请自己检查状态。

此外,对 正在过渡的组件的调用方法将被忽略。对于上述返回 promise 的方法,这种调用会立即解析。它不会等待正在运行的过渡结束。

JavaScript
          const myCarouselEl = document.querySelector('#myCarousel')
const carousel = bootstrap.Carousel.getInstance(myCarouselEl) // Retrieve a Carousel instance

myCarouselEl.addEventListener('slid.bs.carousel', event => {
  carousel.to('2') // Will slide to the slide 2 as soon as the transition to slide 1 is finished
})

carousel.to('1') // Will start sliding to the slide 1 and returns to the caller
carousel.to('2') // !! Will be ignored, as the transition to the slide 1 is not finished !!
        

dispose 方法

请勿呼叫 dispose 紧接着 hide()此时隐藏过渡仍在进行中,因此组件会在过渡中途被销毁。请先等待该承诺:

JavaScript
          const toast = bootstrap.Toast.getInstance('#myToast')

await toast.hide()
toast.dispose()
        

基于事件的等效方法也可以使用:

JavaScript
          const myToastEl = document.querySelector('#myToast')
const toast = bootstrap.Toast.getInstance(myToastEl)

myToastEl.addEventListener('hidden.bs.toast', () => {
  toast.dispose()
})

toast.hide()
        

默认设置

你可以通过修改插件的Constructor.Default对象来更改插件的默认设置:

JavaScript
          // changes default for the toast plugin's `autohide` option to false
bootstrap.Toast.Default.autohide = false
        

方法和属性

每个 Bootstrap 插件都提供以下方法和静态属性。

方法描述
dispose销毁元素的插件实例。(移除DOM元素上存储的数据)
getInstance静态方法,可获取与DOM元素关联的插件实例。
getOrCreateInstance静态方法,可获取与DOM元素关联的插件实例,如果尚未初始化,则创建一个新的实例。
静态属性描述
NAME返回插件名称。(例如:bootstrap.Tooltip.NAME)
VERSION可以通过插件构造函数的 VERSION 属性访问每个 Bootstrap 插件的版本。(例如:bootstrap.Tooltip.VERSION)

消毒剂

一些 JavaScript 组件可以在其配置中呈现或接受任意 HTML。为了防止跨站脚本(XSS)攻击,这些组件在将任何接受 HTML 的选项呈现到页面之前,会使用我们内置的内容清理器对其进行清理。内容清理默认是启用的。具体来说:

  • 如果配置为这样做,弹出框和工具提示可以将任意 HTML 渲染到页面上。
  • 芯片和导航溢出可以为它们的图标选项(dismissIcon、moreIcon 和 [data-bs-overflow-icon])接受 HTML。

默认情况下,工具提示和弹出框内容允许的标签和属性如下。任何未明确允许的标签或属性在清理过程中都会被移除:

const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i

export const DefaultAllowlist: SanitizerAllowList = {
  // 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: []
}

图标选项使用一个独立的、更严格的允许列表,涵盖默认的 SVG 图标和常见的内联图标标记:

/**
 * Allowlist for icon HTML options (Chips `dismissIcon`, NavOverflow `moreIcon`,
 * and markup supplied via `[data-bs-overflow-icon]`). Covers the default SVG
 * icons plus common inline-icon markup. Event-handler attributes and tags not
 * listed here are stripped by `sanitizeHtml`.
 */
export const DefaultIconAllowlist: SanitizerAllowList = {
  '*': ['class', 'role', ARIA_ATTRIBUTE_PATTERN],
  // Attribute names are matched lowercased (see allowedAttribute). `viewBox` is
  // listed as `viewbox` so the default SVG icons keep their coordinate system.
  svg: ['xmlns', 'width', 'height', 'viewbox', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'focusable'],
  path: ['d', 'fill', 'stroke', 'stroke-width', 'fill-rule', 'clip-rule'],
  line: ['x1', 'y1', 'x2', 'y2', 'stroke', 'stroke-width', 'stroke-linecap'],
  circle: ['cx', 'cy', 'r', 'fill', 'stroke', 'stroke-width'],
  rect: ['x', 'y', 'width', 'height', 'rx', 'ry', 'fill', 'stroke', 'stroke-width'],
  polyline: ['points', 'fill', 'stroke', 'stroke-width'],
  polygon: ['points', 'fill', 'stroke', 'stroke-width'],
  g: ['fill', 'stroke', 'stroke-width', 'transform'],
  // No `use` here: `href` / `xlink:href` on <use> can load external SVG
  // fragments. Apps that need sprites can extend this allowlist deliberately.
  span: [],
  i: []
}

使用这些高级选项时请小心。更多信息请参考 OWASP 的跨站脚本预防备忘单。仅因禁用或修改内容消毒而造成的漏洞不被视为 Bootstrap 安全模型的涵盖范围。

你可以向此默认 allowList 添加新值:

JavaScript
          const myDefaultAllowList = bootstrap.Tooltip.Default.allowList

// To allow table elements
myDefaultAllowList.table = []

// To allow td elements and data-bs-option attributes on td elements
myDefaultAllowList.td = ['data-bs-option']

// You can push your custom regex to validate your attributes.
// Be careful about your regular expressions being too lax
const myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)
        

你也可以用专门的库替换我们的消毒器,例如 DOMPurify:

JavaScript
          const myTooltipEl = document.querySelector('#myTooltip')
const tooltip = new bootstrap.Tooltip(myTooltipEl, {
  sanitizeFn(content) {
    return DOMPurify.sanitize(content)
  }
})
        

已禁用 JavaScript

Bootstrap 的插件在 JavaScript 被禁用时没有特殊的回退方案。如果你在意这种情况下的用户体验,可以使用 <noscript> 向你的用户解释情况(以及如何重新启用 JavaScript),和/或添加你自己的自定义回退方案。