概览
点击下面的按钮以显示和关闭弹出框。
<button type="button" class="btn-solid theme-primary"
data-bs-toggle="popover"
data-bs-title="Popover title"
data-bs-content="This is the popover content—make it as long as you want.">
Toggle popover
</button>使用弹出插件时需要注意的事项:
- 弹出窗口依赖于第三方库 Floating UI 用于定位。使用
bootstrap.bundle.min.js这包括 Floating UI,或者通过一个单独的方式包含 Floating UI 导入地图. - 泡芙需要 弹出框插件 作为依赖。
- 使用时,弹出框会自动初始化
data-bs-toggle="popover". - 零长度
title和content值永远不会显示弹出框。 - 指定
container: 'body'以避免在更复杂的组件中(如我们的输入组、按钮组等)出现渲染问题。 - 在隐藏元素上触发弹出框将不起作用。
- 泡芙用于
.disabled或者disabled元素必须在包装元素上触发。 - 当从跨多行的锚点触发时,弹出框将位于锚点整体宽度的中央。使用
.text-nowrap在你的<a>以避免这种行为。 - 弹出框必须在其对应的元素从 DOM 中移除之前被隐藏。
- 弹出框可以通过位于 Shadow DOM 内的元素触发。
默认情况下,该组件使用内置的内容清理器,它会去除任何未明确允许的 HTML 元素。有关更多详细信息,请参阅我们 JavaScript 文档中的 清理器部分。
此组件的动画效果取决于 prefers-reduced-motion 媒体查询。请参阅我们无障碍文档中的 减少动画部分。
继续阅读以查看弹出框如何工作以及一些示例。
示例
现场演示
标题通过 data-bs-title 设置,正文内容通过 data-bs-content 设置。
在你的 HTML 中可以随意使用 title 或 data-bs-title。当使用 title 时,Floating UI 会在元素渲染时自动将其替换为 data-bs-title。
<button type="button" class="btn-solid theme-primary"
data-bs-toggle="popover"
data-bs-title="Popover title"
data-bs-content="And here’s some amazing content. It’s very engaging. Right?">
Toggle popover
</button>职位安排
设置 data-bs-placement 以更改方向。可用的四个选项是:上、右、下和左。在使用 RTL 的 Bootstrap 时,方向会镜像翻转。
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="left"
data-bs-content="Left popover">
Popover on left
</button>
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="top"
data-bs-content="Top popover">
Popover on top
</button>
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="bottom"
data-bs-content="Bottom popover">
Popover on bottom
</button>
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="right"
data-bs-content="Right popover">
Popover on right
</button>响应式放置
使用响应前缀在不同断点更改位置。语法是 breakpoint:placement,其中断点是 sm、md、lg、xl 或 2xl 之一。
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="top md:right lg:bottom"
data-bs-content="This popover changes placement at different breakpoints.">
Top → md:right → lg:bottom
</button>
<button type="button" class="btn-solid theme-secondary"
data-bs-container="body"
data-bs-toggle="popover"
data-bs-placement="left lg:top"
data-bs-content="Responsive popover placement.">
Left → lg:top
</button>调整浏览器大小以查看在不同断点上的弹出位置变化。
自定义 container
当父元素上有一些样式干扰弹出框时,你需要指定一个自定义 container,以便弹出框的 HTML 出现在该元素内。这在响应式表格、输入组等情况下很常见。
const popover = new bootstrap.Popover('.example-popover', {
container: 'body'
})
另一个你可能希望设置明确自定义 container 的情况是在 对话框 内的弹出框,以确保弹出框本身被附加到对话框。这对于包含交互元素的弹出框尤为重要——对话框会捕获焦点,因此除非弹出框是对话框的子元素,否则用户将无法聚焦或激活这些交互元素。
const popover = new bootstrap.Popover('.example-popover', {
container: '.dialog-body'
})
自定义弹出框
你可以使用 CSS 变量 来自定义弹出框的外观。我们使用 data-bs-custom-class="custom-popover" 设置一个自定义类来限定我们的自定义外观,并使用它来覆盖一些本地 CSS 变量。
.custom-popover {
--bs-popover-max-width: 200px;
--bs-popover-border-color: var(--bd-violet-bg);
--bs-popover-header-bg: var(--bd-violet-bg);
--bs-popover-header-color: var(--bs-white);
--bs-popover-body-padding-x: 1rem;
--bs-popover-body-padding-y: 0.5rem;
}
<button type="button" class="btn-solid theme-secondary"
data-bs-toggle="popover" data-bs-placement="right"
data-bs-custom-class="custom-popover"
data-bs-title="Custom popover"
data-bs-content="This popover is themed via CSS variables.">
Custom popover
</button>在下一次点击时关闭
使用 focus 触发器可以在用户下次点击除切换元素之外的元素时关闭弹出框。弹出框内部的点击和聚焦不会关闭它,因此用户可以选择文本或使用内容中的控件。
在下一次点击时解除需要特定的 HTML 才能在不同浏览器和平台上正确工作。你只能使用 <a> 元素,而不能使用 <button> 元素,并且必须包括 tabindex。
<a tabindex="0" class="btn-solid theme-secondary" role="button"
data-bs-toggle="popover"
data-bs-trigger="focus"
data-bs-title="Dismissible popover"
data-bs-content="And here’s some amazing content. It’s very engaging. Right?">
Dismissible popover
</a>
const popover = new bootstrap.Popover('.popover-dismiss', {
trigger: 'focus'
})
显示的弹出框也可以通过按 Escape 键来关闭。与下拉菜单一样,显示在对话框中的弹出框会自动关闭:第一次按 Escape 键会关闭弹出框,随后再次按则会关闭对话框。
禁用的元素
具有 disabled 属性的元素不可交互,这意味着用户无法悬停或点击它们来触发弹出窗口(或工具提示)。作为一种解决方法,你可以从包装器 <div> 或 <span> 触发弹出窗口,理想情况下使用 tabindex="0" 使其可以通过键盘获取焦点。
对于禁用的弹出触发器,你可能也更喜欢data-bs-trigger="hover focus",这样弹出框可以作为即时视觉反馈显示给你的用户,因为他们可能不会期望去点击一个被禁用的元素。
<span class="d-inline-block rounded-3" tabindex="0"
data-bs-toggle="popover"
data-bs-trigger="hover focus"
data-bs-content="Disabled popover">
<button class="btn-solid theme-primary" type="button" disabled>Disabled button</button>
</span>CSS
变量
弹出框在.popover上使用本地 CSS 变量进行实时自定义。CSS 变量的值是从每个组件独特的 Sass map生成的,并应用到前述类上。
// stylelint-disable-next-line scss/dollar-variable-default
$popover-tokens: defaults(
(
--popover-zindex: var(--z-popover),
--popover-max-width: 280px,
--popover-font-size: var(--font-size-sm),
--popover-bg: var(--bg-body),
--popover-border-width: var(--border-width),
--popover-border-color: var(--border-color-translucent),
--popover-border-radius: var(--radius-7),
--popover-inner-border-radius: calc(var(--radius-7) - var(--border-width)),
--popover-box-shadow: var(--box-shadow),
--popover-header-padding-x: var(--spacer),
--popover-header-padding-y: var(--spacer-3),
--popover-header-font-size: var(--font-size-sm),
--popover-header-color: inherit,
--popover-header-bg: var(--bg-1),
--popover-body-padding-x: var(--spacer),
--popover-body-padding-y: var(--spacer-3),
--popover-body-color: var(--fg-body),
--popover-arrow-width: 1rem,
--popover-arrow-height: .5rem,
--popover-arrow-border: var(--popover-border-color),
--popover-transition-property: "opacity",
--popover-transition-duration: .15s,
--popover-transition-timing: linear,
),
$popover-tokens
);
用法
通过 JavaScript 启用弹出框:
const exampleEl = document.getElementById('example')
const popover = new bootstrap.Popover(exampleEl, options)
保持弹出窗口对键盘和辅助技术用户可访问 仅将它们添加到传统上可通过键盘聚焦和交互的 HTML 元素(例如链接或表单控件)。虽然其他 HTML 元素可以通过添加使其可聚焦 tabindex="0",这可能会在非交互元素上为键盘用户创建令人烦恼且令人困惑的制表符停止点,并且目前大多数辅助技术在这种情况下不会宣布弹出窗口。此外,不要仅仅依赖 hover 作为弹出框的触发器,因为这会使键盘用户无法触发它们。
避免在弹出框中添加过多内容 html 选项。一旦弹出框显示,它们的内容将与触发元素绑定 aria-describedby 属性,导致所有弹出内容作为一条长且连续的流向辅助技术用户进行播报。
弹出层不会管理键盘焦点顺序,并且它们在 DOM 中的位置可能是随机的,所以在添加交互元素(如表单或链接)时要小心,因为这可能导致焦点顺序不合理,或者使键盘用户完全无法访问弹出层内容。在必须使用这些元素的情况下,考虑使用对话框代替。
通过数据属性
| 属性 | 描述 |
|---|---|
data-bs-toggle="popover" | 在触发元素上初始化弹出框。 |
data-bs-title | 在弹出标题中显示的标题内容。 |
data-bs-content | 弹出框的主体内容。 |
data-bs-placement | 弹出框相对于触发器的位置。 |
data-bs-trigger | 弹出窗口如何打开(click, hover, focus, manual,或组合)。 |
data-bs-custom-class | 为弹出框添加的额外类名以用于主题化。 |
data-bs-html | 什么时候 true,允许在标题和内容中使用 HTML(处理不受信任的输入时请小心使用)。 |
依赖项
如果你从源代码构建 Bootstrap 的 JS,弹出插件需要以下 JavaScript 文件:
| 文件 | 描述 |
|---|---|
js/src/popover.ts | 主弹出组件 |
js/src/base-component.ts | 基础组件类 |
js/src/tooltip.ts | 工具提示组件 |
js/src/dom/data.ts | 元素数据存储 |
js/src/dom/event-handler.ts | 事件处理工具 |
js/src/dom/manipulator.ts | 数据属性操作 |
js/src/dom/selector-engine.ts | DOM选择器工具 |
js/src/util/config.ts | 配置基类 |
js/src/util/floating-ui.ts | 响应式布局工具 |
js/src/util/index.ts | 核心实用功能 |
js/src/util/sanitizer.ts | HTML 内容净化器 |
js/src/util/template-factory.ts | 模板渲染工具 |
@floating-ui/dom | 第三方定位库 |
选项
由于选项可以通过数据属性或 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合并的结果,其中最新提供的键值会覆盖其他键值。
请注意,出于安全原因,sanitize、sanitizeFn 和 allowList 选项不能通过数据属性提供。
| 名称 | 类型 | 默认 | 描述 |
|---|---|---|---|
allowList | object | 默认值 | 一个包含允许标签和属性的对象。那些未明确允许的将被移除 内容净化器. 在向此列表中添加时要谨慎。 参考 OWASP 跨站脚本防护备忘单 欲了解更多信息。 |
animation | boolean | true | 将 CSS 淡入淡出过渡应用到弹出框。将其设置为 false 添加 .popover-instant 到弹出框,它会关闭淡入淡出效果。 |
boundary | 字符串,元素 | 'clippingParents' | 弹出框的溢出约束边界(仅适用于 Floating UI 的 shift 中间件)。默认情况下,它是 'clippingParents' 并且可以接受一个 HTMLElement 引用(仅通过 JavaScript)。有关更多信息,请参阅 Floating UI 的 交接文件. |
container | 字符串,元素,假 | false | 将弹出框附加到特定元素。示例: container: 'body'此选项特别有用,因为它允许你将弹出框在文档流中靠近触发元素的位置进行定位——这将防止在窗口调整大小时弹出框脱离触发元素飘移。 |
content | 字符串,元素,函数 | '' | 弹出框的文本内容。如果提供了一个函数,它将以附加它的元素作为第一个参数被调用,并且其 this 引用设置为相同的元素。 |
customClass | 字符串,函数 | '' | 在弹出框显示时添加类。请注意,这些类将会在模板中指定的任何类之外添加。要添加多个类,请用空格分隔它们: 'class-1 class-2'你还可以传入一个函数,该函数应返回一个包含额外类名的单个字符串。 |
delay | 数字, 对象 | 0 | 延迟显示和隐藏弹出框(毫秒)——不适用于手动触发类型。如果提供了一个数字,延迟将同时应用于隐藏/显示。对象结构为: delay: { "show": 500, "hide": 100 }. |
fallbackPlacements | array | ['top', 'right', 'bottom', 'left'] | 通过在数组中提供位置列表(按优先顺序)来定义备用位置。有关更多信息,请参阅 Floating UI 的文档 翻转文档. |
html | boolean | false | 允许在弹出框中使用 HTML。如果为真,弹出框中的 HTML 标签将 title 将在弹出框中显示。如果为 false, innerText 该属性将用于将内容插入到 DOM 中。在处理用户生成的输入时,优先使用文本 防止 XSS 攻击. |
offset | 数组,字符串,函数 | [0, 8] | 弹出框相对于其目标的偏移量。你可以在数据属性中传递一个以逗号分隔值的字符串,如: data-bs-offset="10,20"当使用函数来确定偏移量时,它会以包含浮动位置、参考元素和浮动矩形的对象作为第一个参数调用。触发元素的 DOM 节点作为第二个参数传入。该函数必须返回一个包含两个数字的数组: 交叉轴, 主轴. 有关更多信息,请参阅 Floating UI 的 补偿文档. |
placement | 字符串,函数 | 'right' | 如何定位弹出框:上方、下方、左侧、右侧。支持响应式前缀,例如 'top md:right lg:bottom' 在不同的断点更改位置。当使用函数来确定位置时,该函数的第一个参数是弹出框 DOM 节点,第二个参数是触发元素 DOM 节点。 |
floatingConfig | null,对象,函数 | null | 要更改 Bootstrap 的默认 Floating UI 配置,请参阅 Floating UI 的配置当使用函数来创建 Floating UI 配置时,它会被一个包含 Bootstrap 默认 Floating UI 配置的对象调用。它帮助你使用并合并默认配置与自己的配置。该函数必须返回一个用于 Floating UI 的配置对象。 |
sanitize | boolean | true | 启用 内容净化. 如果是真的, template, content 和 title 选项将被清理。在禁用内容清理时要谨慎。 参考 OWASP 跨站脚本防护备忘单 欲了解更多信息。仅因禁用内容清理而导致的漏洞不被视为 Bootstrap 安全模型的范围内。 |
sanitizeFn | 空值,函数 | null | 提供一个替代方案 内容净化 功能。如果你更喜欢使用专用库来执行清理,这可能会很有用。 |
selector | 字符串,假 | false | 如果提供了选择器,popover 对象将被委托给指定的目标。实际上,这也用于将 popover 应用于动态添加的 DOM 元素。jQuery.on 支持)。参见 这个问题. 注意: title 属性不得用作选择器。 |
template | string | '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>' | 创建弹出框时使用的基础 HTML。弹出框的 title 将被注入到 .popover-header. 弹出框的 content 将被注入到 .popover-body. .popover-arrow 将成为弹出框的箭头。最外层的包装元素应该有 .popover 类和 role="tooltip". |
title | 字符串,元素,函数 | '' | 弹出标题。如果提供了一个函数,它将以所附元素作为第一个参数调用,并且与它的 this 引用设置为相同的元素。 |
trigger | string | 'click' | 弹出框的触发方式:点击、悬停、聚焦、手动。你可以传入多个触发方式,用空格分隔。 'manual' 表示弹出框将通过编程方式触发 .popover('show'), .popover('hide') 和 .popover('toggle') 方法;此值不能与任何其他触发器组合。 'hover' 单独使用会导致无法通过键盘触发弹出框,只有在存在为键盘用户提供相同信息的替代方法时才应使用。 |
使用带有 floatingConfig 的函数
const popover = new bootstrap.Popover(element, {
floatingConfig(defaultBsFloatingConfig) {
// const newFloatingConfig = {...}
// use defaultBsFloatingConfig if needed...
// return newFloatingConfig
}
})
方法
显示或隐藏组件的方法会返回一个 Promise。 当过渡结束时,该 Promise 会被解析,所以 await 会在 shown.bs.* 或 hidden.bs.* 监听器运行的同一时刻继续。方法仍会立即返回,并且永远不会阻塞调用者。对已在过渡中的组件进行调用不会有任何效果,并会立即解析。在我们的 JavaScript 文档中了解更多。
| 方法 | 描述 |
|---|---|
disable | 移除元素显示弹出框的能力。只有在重新启用后,弹出框才能显示。 |
dispose | 隐藏并销毁元素的弹出框(移除 DOM 元素上存储的数据)。使用委托的弹出框(通过创建时使用) 这 selector 选项) 不能在后代触发元素上单独销毁。 |
enable | 赋予一个元素显示弹出框的能力。 弹出框默认启用。 |
getInstance | 静态 一种允许你获取与 DOM 元素关联的弹出实例的方法。 |
getOrCreateInstance | 静态 一种方法,允许你获取与 DOM 元素关联的弹出框实例,或者在未初始化的情况下创建一个新的实例。 |
hide | 隐藏元素的弹出框。 返回一个在弹出框隐藏后解决的 promise (即在……之后 hidden.bs.popover 事件触发)。这被认为是对弹出框的“手动”触发。 |
setContent | 提供了一种在初始化后更改弹出内容的方法。 |
show | 显示元素的弹出框。 返回一个在弹出框显示后解决的 promise (即在……之后 shown.bs.popover 事件触发)。这被视为“手动”触发弹出框。标题和内容都为空的弹出框永远不会显示。 |
toggle | 切换元素的弹出框。 返回一个在弹出框显示或隐藏后解决的承诺 (即在……之后 shown.bs.popover 或 hidden.bs.popover 事件触发)。这被认为是对弹出框的“手动”触发。 |
toggleEnabled | 切换元素弹出框显示或隐藏的能力。 |
update | 更新元素弹出框的位置。 |
// getOrCreateInstance example
const popover = bootstrap.Popover.getOrCreateInstance('#example') // Returns a Bootstrap popover instance
// setContent example
popover.setContent({
'.popover-header': 'another title',
'.popover-body': 'another content'
})
setContent 方法接受一个 object 参数,其中每个属性键都是弹出框模板中一个有效的 string 选择器,每个相关的属性值可以是 string | element | function | null
事件
| 事件 | 描述 |
|---|---|
hide.bs.popover | 当……时,此事件会立即触发 hide 实例方法已被调用。 |
hidden.bs.popover | 当弹出框已完成从用户界面隐藏时(将等待 CSS 过渡完成)会触发此事件。 |
inserted.bs.popover | 此事件在之后触发 show.bs.popover 即使弹出模板已被添加到 DOM 中。 |
show.bs.popover | 当...时此事件立即触发 show 实例方法被调用。 |
shown.bs.popover | 当弹出框已对用户可见时会触发此事件(将等待 CSS 过渡完成)。 |
const myPopoverTrigger = document.getElementById('myPopover')
myPopoverTrigger.addEventListener('hidden.bs.popover', () => {
// do something...
})