Skip to main content Skip to docs navigation

了解BootstrapJavaScript插件,学习每个插件及其API参数方法等。

单个引用或者编译

插件可以单独包含(使用Bootstrap的独立 js/dist/*.js),也可以同时使用 bootstrap.js 或压缩的 bootstrap.min.js (不要同时包含两个)。

如果使用bundler(Webpack,Rollup ...),则可以使用UMD就绪的/js/dist/*.js文件。

JavaScript与框架一起使用

虽然Bootstrap CSS可以与任何框架一起使用,但Bootstrap JavaScript与React、Vue和Angular等JavaScript框架并不完全兼容,因为这些框架假定对DOM有充分的了解。Bootstrap和框架都可能试图变异同一个DOM元素,从而导致像下拉菜单这样的错误,并停留在“打开”位置。

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

使用Bootstrap作为模块

自己试试吧!从twbs/examples存储库下载使用Bootstrap作为ES模块的源代码和工作演示。您也可以在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 "../".

要解决这个问题,您可以使用mportmap来解析任意模块名称以完成路径。如果目标浏览器不支持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/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <title>Hello, modularity!</title>
  </head>
  <body>
    <h1>Hello, modularity!</h1>
    <button id="popoverButton" type="button" class="btn btn-primary btn-lg" class="btn btn-lg btn-danger" 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/core@2.11.6/dist/umd/popper.min.js",
        "bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.esm.min.js"
      }
    }
    </script>
    <script type="module">
      import * as bootstrap from 'bootstrap'

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

依赖关系

一些插件和CSS组件依赖于其他插件。如果你单独调用某个插件,请先在文档中检查它们的依赖关系。

比如下拉菜单dropdowns、提示组件popovers、冒泡组件等都提依赖于Popper

数据属性

几乎所有的引导插件都可以通过带有数据属性的HTML(我们使用JavaScript功能的首选方式)来启用和配置。确保在单个元素上只使用一组数据属性(例如,不能从同一个按钮触发工具提示和模态)。

As options can be passed via data attributes or JavaScript, you can append an option name to data-bs-, as in data-bs-animation="{value}". Make sure to change the case type of the option name from “camelCase” to “kebab-case” when passing the options via data attributes. For example, use data-bs-custom-class="beautifier" instead of data-bs-customClass="beautifier".

As of Bootstrap 5.2.0, all components support an experimental reserved data attribute data-bs-config that can house simple component configuration as a JSON string. When an element has data-bs-config='{"delay":0, "title":123}' and data-bs-title="456" attributes, the final title value will be 456 and the separate data attributes will override values given on data-bs-config. In addition, existing data attributes are able to house JSON values like data-bs-delay='{"show":0,"hide":150}'.

选择器

目前,为了查询DOM元素,我们使用原生方法 querySelectorquerySelectorAll ,因为性能原因,所以必须使用有效的选择器。如果您使用特殊的选择器,例如: collapse:Example ,请确保对它们进行转义。

事件

Bootstrap为大多数插件的独特动作提供自定义事件。一般来说,这些动词都有不定式和过去分词形式,其中不定式(如 shown)是在事件开始时触发的,它的过去分词形式(如 shown)是在动作完成时触发的。

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

const myModal = document.querySelector('#myModal')

myModal.addEventListener('show.bs.modal', event => {
  if (!data) {
    return event.preventDefault() // stops modal from being shown
  }
})

编程化的 API

所有的构造函数都接受一个可选的option对象,或者什么都不接受(这将启动一个默认行为的插件):

const myModalEl = document.querySelector('#myModal')
const modal = new bootstrap.Modal(myModalEl) // initialized with defaults

const configObject = { keyboard: false }
const modal1 = new bootstrap.Modal(myModalEl, configObject) // initialized with no keyboard

如果你想获得一个特定的插件实例,每个插件都会公开一个getInstance方法。你可以直接从元素中检索它:bootstrap.Popover.getInstance(myPopoverEl)

bootstrap.Popover.getInstance(myPopoverEl)

This method will return null if an instance is not initiated over the requested element.

Alternatively, getOrCreateInstance can be used to get the instance associated with a DOM element, or create a new one in case it wasn’t initialized.

bootstrap.Popover.getOrCreateInstance(myPopoverEl, configObject)

在实例未初始化的情况下,它可以接受并使用可选的配置对象作为第二个参数。

CSS selectors in constructors

In addition to the getInstance and getOrCreateInstance methods, all plugin constructors can accept a DOM element or a valid CSS selector as the first argument. Plugin elements are found with the querySelector method since our plugins only support a single element.

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')

异步函数和转换

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

const myCollapseEl = document.querySelector('#myCollapse')

myCollapseEl.addEventListener('shown.bs.collapse', event => {
  // Action to execute once the collapsible area is expanded
})

此外,对转换组件的方法调用将被忽略

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 method

While it may seem correct to use the dispose method immediately after hide(), it will lead to incorrect results. Here’s an example of the problem use:

const myModal = document.querySelector('#myModal')
myModal.hide() // it is asynchronous

myModal.addEventListener('shown.bs.hidden', event => {
  myModal.dispose()
})

Default settings

You can change the default settings for a plugin by modifying the plugin’s Constructor.Default object:

// changes default for the modal plugin's `keyboard` option to false
bootstrap.Modal.Default.keyboard = false

Methods and properties

Every Bootstrap plugin exposes the following methods and static properties.

Method Description
dispose Destroys an element’s modal. (Removes stored data on the DOM element)
getInstance Static method which allows you to get the modal instance associated with a DOM element.
getOrCreateInstance Static method which allows you to get the modal instance associated with a DOM element, or create a new one in case it wasn’t initialized.
Static property Description
NAME Returns the plugin name. (Example: bootstrap.Tooltip.NAME)
VERSION The version of each of Bootstrap’s plugins can be accessed via the VERSION property of the plugin’s constructor (Example: bootstrap.Tooltip.VERSION)

清理器

工具提示和弹出窗口使用我们的内置清理器来清理接受HTML的选项。

默认的 allowList 值如下:

const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
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: [],
  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 添加新值,可以执行以下操作:

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,则应执行以下操作:

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

jQuery使用

在Bootstrap 5中不需要jQuery,但仍然可以将我们的组件与jQuery一起使用。如果Bootstrap在window对象中检测到jQuery ,它将在jQuery的插件系统中添加所有组件。这允许您执行以下操作:

// to enable tooltips with the default configuration
$('[data-bs-toggle="tooltip"]').tooltip()

// to initialize tooltips with given configuration
$('[data-bs-toggle="tooltip"]').tooltip({
  boundary: 'clippingParents',
  customClass: 'myClass'
})

// to trigger the `show` method
$('#myTooltip').tooltip('show')

The same goes for our other components.

没有冲突(只有在使用jQuery的情况下)

有时,在其他UI框架中使用引导插件是必要的。在这些情况下,名称空间冲突偶尔会发生。如果发生这种情况,你可以在你想要恢复值的插件上调用 .noConflict

const bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value
$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the Bootstrap functionality

Bootstrap不正式支持Prototype或jQuery UI等第三方JavaScript库。尽管没有 .noConflict和同名事件,但可能存在兼容性问题,您需要自行解决。

jQuery 事件

如果 jQuery 出现在 window 对象中,并且没有设置 data-bs-no-jquery 属性,那么Bootstrap将检测jQuery。如果发现了jQuery, Bootstrap将通过jQuery的事件系统发出事件。因此,如果您想监听Bootstrap的事件,就必须使用jQuery方法(.on.one)而不是 addEventListener

$('#myTab a').on('shown.bs.tab', () => {
  // do something...
})

禁用JavaScript

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