阅读(2199) (2)

Bootstrap5 JavaScript

2021-08-30 16:20:53 更新

通过使用可选的 JavaScript 插件,让 Bootstrap 变得栩栩如生。在本章中你将了解每个插件以及 Bootstrap 提供的 data 和编程式 API 等更多信息。

集成包

每个插件都可以被单独引入(使用对应每个 Bootstrap 插件的​ js/dist/*.js​ 文件),也可以通过​ bootstrap.js​ 或压缩版的​ bootstrap.min.js​ 文件一次性引入所有插件(选一个即可,不要同时使用)。

如果使用打包程序(Webpack、Rollup 等),你可以使用支持 UMD 格式的​ /js/dist/*.js​ 文件。

将 Bootstrap 作为模块使用

我们为 Bootstrap 提供了一个 ESM 模块(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>

不兼容的插件

由于浏览器的限制,某些插件,例如下拉菜单(Dropdown)、工具提示(Tooltip)和弹出框(Popover)插件,不能通过设置为 ​module ​类型的 ​<script>​ 标签使用,由于它们都依赖 Popper。有关此问题的更多信息,请见 这里

依赖项

某些插件和 CSS 组件依赖于其它插件。如果你选择单独引入某个插件,请确保在文档中检查其是否存在依赖其它插件的情况。

下拉菜单(dropdown)、弹出框(popover)和工具提示(tooltip)组件依赖 Popper

仍然需要用到 jQuery 吗?没有问题!

Bootstrap 5 被设计为不依赖 jQuery,但仍可以将 Bootstrap 的组件与 jQuery 一起使用。如果 Bootstrap 在 ​window ​对象上检测到了 ​jQuery ​,它将把所有的 Bootstrap 插件添加到 jQuery 的插件系统中。也就意味着你将来能够通过 ​$('[data-bs-toggle="tooltip"]').tooltip() ​来调用工具提示(tooltip)组件。同理,其它组件也类似。

插件的 data 属性 API

几乎所有的 Bootstrap 插件都可以通过带有 data 属性的 HTML 元素单独开启和配置(我们推荐 JavaScript API 为首选方式)。请确保 仅在单个 HTML 元素上使用一组 data 属性 (例如,你不能通过同一按钮触发工具提示和模态框。)

选择器

目前,由于性能的原因,我们使用原生方法 querySelector 和 querySelectorAll 来查询 DOM 元素,因此你必须使用 合法的选择器。 如果使用特殊的选择器,例如 collapse:Example ,请确保对其进行转义。

事件

Bootstrap 为大多数插件的独特行为提供了自定义事件。通常,事件的命名以不定式或过去分词形式出现,例如,在事件开始时触发的事件名时不定式形式的(例如 ​show​),在事件完成时触发的事件名是过去分词形式的(例如 ​shown​)。

所有不定式形式命名的事件都提供 preventDefault() 功能。这就赋予了你在动作开始之前将其停止的能力。如果事件处理函数的返回值是 false,将自动调用​ preventDefault()​。

var myModal = document.getElementById('myModal')

myModal.addEventListener('show.bs.modal', function (event) {
  if (!data) {
    return event.preventDefault() // 停止即将展示的模态框(modal)
  }
})

jQuery 事件

如果 ​jQuery​ 存在于 ​window ​对象上,并且 ​<body>​ 元素上没有设置 ​data-bs-no-jquery​ 属性,Bootstrap 将认为 jQuery 存在。如果检测到了 jQuery,Bootstrap 将基于 jQuery 的事件系统触发相应的事件。因此,如果你想监听 Bootstrap 的事件,就必须使用 jQuery 的方法(例如 ​.on​、​.one​)而不能使用 ​addEventListener​。
$('#myTab a').on('shown.bs.tab', function () {
// do something...
})

编程式 API

所有构造函数都可以接受对象类型的参数或没有参数(将以默认行为初始化插件):

var myModalEl = document.getElementById('myModal')

var modal = new bootstrap.Modal(myModalEl) // 以默认值初始化
var modal = new bootstrap.Modal(myModalEl, { keyboard: false }) // 以对象参数初始化

如果你想获取某个插件的特定实例,可以调用每个插件都暴露出来的 ​getInstance​ 方法。为了直接从元素中获取插件的实例对象,请执行以下操作: ​bootstrap.Popover.getInstance(myPopoverEl)​。

构造函数中的 CSS 选择器

您还可以使用 CSS 选择器作为第一个参数而不是 DOM 元素来初始化插件。目前插件的元素是通过​querySelector​方法找到的,因为我们的插件只支持单个元素。

var modal = new bootstrap.Modal('#myModal')
var dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')

异步编程和 transitions

所有编程形式的 API 方法都是 异步的,并在 transition 开始之后、结束之前返回到调用者。

为了在 transition 完成后执行某个动作,你可以监听相应的事件。

var myCollapseEl = document.getElementById('myCollapse')

myCollapseEl.addEventListener('shown.bs.collapse', function (event) {
  // 可折叠区域被展开时,此处的动作将被执行一次
})

另外,对 正在 transitioning 状态的组件调用的任何方法都将被忽略

var myCarouselEl = document.getElementById('myCarousel')
var carousel = bootstrap.Carousel.getInstance(myCarouselEl) // 获取轮播(Carousel)组件的实例

myCarouselEl.addEventListener('slid.bs.carousel', function (event) {
  carousel.to('2') // 当滑动到幻灯片 1 之后,将立即滑动到幻灯片 2
})

carousel.to('1') // 开始滑动到幻灯片 1 并返回到回调者
carousel.to('2') // !! 将会被忽略,因为滑动到幻灯片 1 的转换动作还未完成 !!

默认设置

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

// 将模态框(modal)插件的 `keyboard` 的默认值修改为 false
bootstrap.Modal.Default.keyboard = false

避免冲突(仅针对使用 jQuery 的情况)

有些时候需要将 Bootstrap 插件与其它 UI 框架一起使用。在这种情况下,难免发生命名空间的冲突。如果发生这种情况,你可以在需要还原的插件上调用​ .noConflict​ 函数。

var bootstrapButton = $.fn.button.noConflict() // 重置 $.fn.button 为先前的值
$.fn.bootstrapBtn = bootstrapButton // 为 $().bootstrapBtn 赋予 Bootstrap 的功能

版本号

每个 Bootstrap 插件都可以通过其构造函数上的 VERSION 属性进行访问。例如,以工具提示(tooltip)插件为例:

bootstrap.Tooltip.VERSION // => "5.1.0"

JavaScript 被禁用的话没有降级方案

一旦 JavaScript 被禁用,Bootstrap 的插件没有优雅降级的方案。如果你很关心在这种情况下的用户体验,请使用 <noscript> 标签并向你的用户解释情况(以及重新启用 JavaScript 的方法),和/或添加你自己的降级方案。

第三方工具库

Bootstrap 不对第三方工具库提供支持,例如 Prototype 或 jQuery UI。尽管存在 ​.noConflict​ 和基于命名空间的事件,但仍可能需要您自行解决兼容性问题。

清理程序

工具提示(tooltip)和弹出框(popover)可以接受 HTML 代码作为参数,但会使用 Bootstrap 内置的清理程序对 HTML 代码进行清理。

allowList​ 的默认值如下所示:

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: []
}

如果要向 ​whiteList ​添加新值,则可以执行如下操作:

var myDefaultAllowList = bootstrap.Tooltip.Default.allowList

// 添加 table 元素
myDefaultAllowList.table = []

// 添加 td 元素以及 td 元素的 data-bs-option 属性
myDefaultAllowList.td = ['data-bs-option']

// 你可以添加自定义的正则表达式来对属性进行校验。
// 请提防过于宽松的正则表达式
var myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)

如果你因为喜欢使用专用的工具库(例如 DOMPurify)并想绕过 Bootstrap 的清理程序,则可以这样操作:

var yourTooltipEl = document.getElementById('yourTooltip')
var tooltip = new bootstrap.Tooltip(yourTooltipEl, {
  sanitizeFn: function (content) {
    return DOMPurify.sanitize(content)
  }
})