Popovers
将 Bootstrap 弹出窗口(如 iOS 中的弹出窗口)添加到网站上的任何元素的文档和示例。
概述
¥Overview
使用 popover 插件时需要注意的事项:
¥Things to know when using the popover plugin:
-
Popovers 依赖第三方库 Popper 进行定位。你必须在
bootstrap.js
之前包含 popper.min.js,或者使用包含 Popper 的bootstrap.bundle.min.js
。¥Popovers rely on the third party library Popper for positioning. You must include popper.min.js before
bootstrap.js
, or use onebootstrap.bundle.min.js
which contains Popper. -
弹出框需要 弹出框插件 作为依赖。
¥Popovers require the popover plugin as a dependency.
-
出于性能原因,弹出窗口是可选的,因此你必须自己初始化它们。
¥Popovers are opt-in for performance reasons, so you must initialize them yourself.
-
零长度
title
和content
值永远不会显示弹出窗口。¥Zero-length
title
andcontent
values will never show a popover. -
指定
container: 'body'
以避免更复杂的组件(例如我们的输入组、按钮组等)中出现渲染问题。¥Specify
container: 'body'
to avoid rendering problems in more complex components (like our input groups, button groups, etc). -
在隐藏元素上触发弹出窗口将不起作用。
¥Triggering popovers on hidden elements will not work.
-
.disabled
或disabled
元素的弹出窗口必须在封装元素上触发。¥Popovers for
.disabled
ordisabled
elements must be triggered on a wrapper element. -
当从跨多行的锚点触发时,弹出窗口将位于锚点整体宽度的中间。在
<a>
上使用.text-nowrap
可以避免这种行为。¥When triggered from anchors that wrap across multiple lines, popovers will be centered between the anchors’ overall width. Use
.text-nowrap
on your<a>
s to avoid this behavior. -
在从 DOM 中删除相应的元素之前,必须隐藏弹出窗口。
¥Popovers must be hidden before their corresponding elements have been removed from the DOM.
-
弹出窗口可以通过影子 DOM 内的元素来触发。
¥Popovers can be triggered thanks to an element inside a shadow DOM.
By default, this component uses the built-in content sanitizer, which strips out any HTML elements that are not explicitly allowed. See the sanitizer section in our JavaScript documentation for more details.
The animation effect of this component is dependent on the prefers-reduced-motion
media query. See the reduced motion section of our accessibility documentation.
继续阅读一些示例,了解弹出窗口如何工作。
¥Keep reading to see how popovers work with some examples.
示例
¥Examples
启用弹出窗口
¥Enable popovers
如上所述,你必须先初始化弹出窗口,然后才能使用它们。初始化页面上所有弹出窗口的一种方法是通过它们的 data-bs-toggle
属性选择它们,如下所示:
¥As mentioned above, you must initialize popovers before they can be used. One way to initialize all popovers on a page would be to select them by their data-bs-toggle
attribute, like so:
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
在线演示
¥Live demo
我们使用类似于上面代码片段的 JavaScript 来渲染以下实时弹出窗口。标题通过 data-bs-title
设置,正文内容通过 data-bs-content
设置。
¥We use JavaScript similar to the snippet above to render the following live popover. Titles are set via data-bs-title
and body content is set via data-bs-content
.
Feel free to use either title
or data-bs-title
in your HTML. When title
is used, Popper will replace it automatically with data-bs-title
when the element is rendered.
<button type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" data-bs-title="Popover title" data-bs-content="And here’s some amazing content. It’s very engaging. Right?">Click to toggle popover</button>
四个方向
¥Four directions
有四个选项可供选择:上、右、下、左。在 RTL 中使用 Bootstrap 时,方向会被镜像。设置 data-bs-placement
以改变方向。
¥Four options are available: top, right, bottom, and left. Directions are mirrored when using Bootstrap in RTL. Set data-bs-placement
to change the direction.
<button type="button" class="btn btn-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 btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Right popover">
Popover on right
</button>
<button type="button" class="btn btn-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 btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Left popover">
Popover on left
</button>
定制 container
¥Custom container
如果父元素上的某些样式会干扰弹出窗口,你需要指定自定义 container
,以便弹出窗口的 HTML 显示在父元素内。这在响应式表、输入组等中很常见。
¥When you have some styles on a parent element that interfere with a popover, you’ll want to specify a custom container
so that the popover’s HTML appears within that element instead. This is common in responsive tables, input groups, and the like.
const popover = new bootstrap.Popover('.example-popover', {
container: 'body'
})
另一种需要设置显式自定义 container
的情况是 模态对话框 中的弹出窗口,以确保弹出窗口本身附加到模态框中。这对于包含交互元素的弹出窗口尤其重要 - 模态对话框会捕获焦点,因此除非弹出窗口是模态对话框的子元素,否则用户将无法获得焦点或激活这些交互元素。
¥Another situation where you’ll want to set an explicit custom container
are popovers inside a modal dialog, to make sure that the popover itself is appended to the modal. This is particularly important for popovers that contain interactive elements – modal dialogs will trap focus, so unless the popover is a child element of the modal, users won’t be able to focus or activate these interactive elements.
const popover = new bootstrap.Popover('.example-popover', {
container: '.modal-body'
})
定制弹出窗口
¥Custom popovers
Added in v5.2.0你可以使用 CSS 变量 自定义弹出窗口的外观。我们使用 data-bs-custom-class="custom-popover"
设置自定义类来限定自定义外观的范围,并使用它来覆盖一些本地 CSS 变量。
¥You can customize the appearance of popovers using CSS variables. We set a custom class with data-bs-custom-class="custom-popover"
to scope our custom appearance and use it to override some of the local CSS variables.
.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: .5rem;
}
<button type="button" class="btn btn-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>
下次点击时关闭
¥Dismiss on next click
使用 focus
触发器在用户下次点击切换元素以外的元素时关闭弹出窗口。
¥Use the focus
trigger to dismiss popovers on the user’s next click of an element other than the toggle element.
下次点击时关闭需要特定的 HTML 才能实现正确的跨浏览器和跨平台行为。你只能使用 <a>
元素,不能使用 <button>
,并且必须包含 tabindex
。
¥Dismissing on next click requires specific HTML for proper cross-browser and cross-platform behavior. You can only use <a>
elements, not <button>
s, and you must include a tabindex
.
<a tabindex="0" class="btn btn-lg btn-danger" 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'
})
禁用元素
¥Disabled elements
带有 disabled
属性的元素不具有交互性,这意味着用户无法悬停或点击它们来触发弹出窗口(或工具提示)。作为一种解决方法,你需要从封装器 <div>
或 <span>
触发弹出窗口,理想情况下,使用 tabindex="0"
使其可键盘对焦。
¥Elements with the disabled
attribute aren’t interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you’ll want to trigger the popover from a wrapper <div>
or <span>
, ideally made keyboard-focusable using tabindex="0"
.
对于禁用的弹出窗口触发器,你可能还更喜欢 data-bs-trigger="hover focus"
,以便弹出窗口显示为用户的即时视觉反馈,因为他们可能不希望单击禁用的元素。
¥For disabled popover triggers, you may also prefer data-bs-trigger="hover focus"
so that the popover appears as immediate visual feedback to your users as they may not expect to click on a disabled element.
<span class="d-inline-block" tabindex="0" data-bs-toggle="popover" data-bs-trigger="hover focus" data-bs-content="Disabled popover">
<button class="btn btn-primary" type="button" disabled>Disabled button</button>
</span>
CSS
变量
¥Variables
Added in v5.2.0作为 Bootstrap 不断发展的 CSS 变量方法的一部分,弹出窗口现在使用 .popover
上的本地 CSS 变量来增强实时自定义。CSS 变量的值是通过 Sass 设置的,因此仍然支持 Sass 自定义。
¥As part of Bootstrap’s evolving CSS variables approach, popovers now use local CSS variables on .popover
for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
--#{$prefix}popover-zindex: #{$zindex-popover};
--#{$prefix}popover-max-width: #{$popover-max-width};
@include rfs($popover-font-size, --#{$prefix}popover-font-size);
--#{$prefix}popover-bg: #{$popover-bg};
--#{$prefix}popover-border-width: #{$popover-border-width};
--#{$prefix}popover-border-color: #{$popover-border-color};
--#{$prefix}popover-border-radius: #{$popover-border-radius};
--#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
--#{$prefix}popover-box-shadow: #{$popover-box-shadow};
--#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
--#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
@include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
--#{$prefix}popover-header-color: #{$popover-header-color};
--#{$prefix}popover-header-bg: #{$popover-header-bg};
--#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
--#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
--#{$prefix}popover-body-color: #{$popover-body-color};
--#{$prefix}popover-arrow-width: #{$popover-arrow-width};
--#{$prefix}popover-arrow-height: #{$popover-arrow-height};
--#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
Sass 变量
¥Sass variables
$popover-font-size: $font-size-sm;
$popover-bg: var(--#{$prefix}body-bg);
$popover-max-width: 276px;
$popover-border-width: var(--#{$prefix}border-width);
$popover-border-color: var(--#{$prefix}border-color-translucent);
$popover-border-radius: var(--#{$prefix}border-radius-lg);
$popover-inner-border-radius: calc(#{$popover-border-radius} - #{$popover-border-width}); // stylelint-disable-line function-disallowed-list
$popover-box-shadow: var(--#{$prefix}box-shadow);
$popover-header-font-size: $font-size-base;
$popover-header-bg: var(--#{$prefix}secondary-bg);
$popover-header-color: $headings-color;
$popover-header-padding-y: .5rem;
$popover-header-padding-x: $spacer;
$popover-body-color: var(--#{$prefix}body-color);
$popover-body-padding-y: $spacer;
$popover-body-padding-x: $spacer;
$popover-arrow-width: 1rem;
$popover-arrow-height: .5rem;
用法
¥Usage
通过 JavaScript 启用弹出窗口:
¥Enable popovers via JavaScript:
const exampleEl = document.getElementById('example')
const popover = new bootstrap.Popover(exampleEl, options)
通过仅将弹出窗口添加到传统上可通过键盘聚焦且可交互的 HTML 元素(例如链接或表单控件)中,确保键盘用户和辅助技术用户能够访问弹出窗口。虽然可以通过添加 tabindex="0"
使其他 HTML 元素可聚焦,但这会在非交互元素上为键盘用户创建恼人且令人困惑的制表位,并且大多数辅助技术目前不会在这种情况下播报弹出窗口。此外,不要仅仅依赖 hover
作为弹出窗口的触发器,因为这将使键盘用户无法触发它们。
¥Keep popovers accessible to keyboard and assistive technology users by only adding them to HTML elements that are traditionally keyboard-focusable and interactive (such as links or form controls). While other HTML elements can be made focusable by adding tabindex="0"
, this can create annoying and confusing tab stops on non-interactive elements for keyboard users, and most assistive technologies currently do not announce popovers in this situation. Additionally, do not rely solely on hover
as the trigger for your popovers as this will make them impossible to trigger for keyboard users.
使用 html
选项,避免在弹出窗口中添加过多内容。弹出窗口显示后,其内容将通过 aria-describedby
属性绑定到触发元素,从而使弹出窗口的所有内容以一条长且不间断的流的形式显示给辅助技术用户。
¥Avoid adding an excessive amount of content in popovers with the html
option. Once popovers are displayed, their content is tied to the trigger element with the aria-describedby
attribute, causing all of the popover’s content to be announced to assistive technology users as one long, uninterrupted stream.
弹出框不管理键盘焦点顺序,它们在 DOM 中的位置可能是随机的,因此在添加交互元素(如表单或链接)时要小心,因为这可能会导致焦点顺序不合理,或者使键盘用户完全无法访问弹出框内容本身。如果必须使用这些元素,请考虑使用模态对话框。
¥Popovers do not manage keyboard focus order, and their placement can be random in the DOM, so be careful when adding interactive elements (like forms or links), as it may lead to an illogical focus order or make the popover content itself completely unreachable for keyboard users. In cases where you must use these elements, consider using a modal dialog instead.
选项
¥Options
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}'
.
The final configuration object is the merged result of data-bs-config
, data-bs-
, and js object
where the latest given key-value overrides the others.
请注意,出于安全原因,不能使用数据属性提供 sanitize
、sanitizeFn
和 allowList
选项。
¥Note that for security reasons the sanitize
, sanitizeFn
, and allowList
options cannot be supplied using data attributes.
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
allowList | object | 默认值 | 包含允许的属性和标签的对象。 |
animation | boolean | true | 对弹出窗口应用 CSS 淡入淡出过渡效果。 |
boundary | 字符串,元素 | 'clippingParents' | 弹出窗口的溢出约束边界(仅适用于 Popper 的 preventOverflow 修饰符)。默认情况下,它是 'clippingParents' ,可以接受 HTMLElement 引用(仅通过 JavaScript)。有关更多信息,请参阅 Popper 的 detectOverflow 文档。 |
container | 字符串,元素,false | false | 将弹出窗口附加到特定元素。示例:container: 'body' 。此选项非常有用,因为它允许你将弹出窗口放置在文档流中触发元素附近。 - 这将防止弹出窗口在窗口调整大小时从触发元素上浮开。 |
content | 字符串,元素,函数 | '' | 弹出框的文本内容。如果指定了一个函数,它将被调用,并将其 this 引用设置为弹出窗口所附加的元素。 |
customClass | 字符串,函数 | '' | 在弹出窗口显示时为其添加类。请注意,除了模板中指定的任何类之外,还将添加这些类。要添加多个类,请用空格分隔:'class-1 class-2' 。你还可以传递一个函数,该函数应返回包含其他类名的单个字符串。 |
delay | 数字,对象 | 0 | 显示和隐藏弹窗的延迟时间(毫秒) - 不适用于手动触发类型。如果指定了一个数字,则隐藏/显示都会应用延迟。对象结构如下:delay: { "show": 500, "hide": 100 } 。 |
fallbackPlacements | 字符串,数组 | ['top', 'right', 'bottom', 'left'] | 通过提供数组中的位置列表(按优先顺序)来定义后备位置。有关更多信息,请参阅 Popper 的 行为文档。 |
html | boolean | false | 允许在弹出窗口中使用 HTML。如果为 true,则弹出窗口 title 中的 HTML 标签将在弹出窗口内渲染。如果为 false,则 innerText 属性将用于将内容插入 DOM。如果你担心 XSS 攻击,请使用文本。 |
offset | 数字,字符串,函数 | [0, 8] | 弹出窗口相对于其目标元素的偏移量。你可以在数据属性中传递一个以逗号分隔的字符串,例如:data-bs-offset="10,20" 。当使用函数确定偏移量时,会使用包含 Popper 位置、引用和 Popper 矩形的对象作为其第一个参数来调用该函数。触发元素的 DOM 节点作为第二个参数传递。该函数必须返回一个包含两个数字的数组:skidding, distance.有关更多信息,请参阅 Popper 的 偏移文档。 |
placement | 字符串,函数 | 'right' | 如何定位弹出窗口:自动、顶部、底部、左侧、右侧。指定 auto 后,它将动态重新调整弹出窗口的方向。当使用函数确定位置时,会使用弹出窗口 DOM 节点作为其第一个参数,使用触发元素 DOM 节点作为其第二个参数来调用该函数。this 上下文设置为弹出窗口实例。 |
popperConfig | null,对象,函数 | null | 要更改 Bootstrap 的默认 Popper 配置,请参阅 Popper 配置。当使用函数创建 Popper 配置时,会使用包含 Bootstrap 默认 Popper 配置的对象来调用该函数。它可以帮助你使用默认配置并将其与你自己的配置合并。该函数必须返回 Popper 的配置对象。 |
sanitize | boolean | true | 启用或禁用清理功能。如果激活,'template' 、'content' 和 'title' 选项将被过滤。 |
sanitizeFn | null,函数 | null | 这里你可以提供自己的清理函数。如果你更喜欢使用专用库来执行清理,这将非常有用。 |
selector | 字符串,false | false | 如果指定了选择器,弹出窗口对象将被委托给指定的目标。实际操作中,它也用于将弹出窗口应用于动态添加的 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' 将导致无法通过键盘触发的弹出窗口,因此仅在存在其他方法可以为键盘用户传达相同信息时才应使用。 |
单个弹出窗口的数据属性
¥Data attributes for individual popovers
也可以通过使用数据属性来指定单个弹出窗口的选项,如上所述。
¥Options for individual popovers can alternatively be specified through the use of data attributes, as explained above.
将函数与 popperConfig
一起使用
¥Using function with popperConfig
const popover = new bootstrap.Popover(element, {
popperConfig(defaultBsPopperConfig) {
// const newPopperConfig = {...}
// use defaultBsPopperConfig if needed...
// return newPopperConfig
}
})
方法
¥Methods
All API methods are asynchronous and start a transition. They return to the caller as soon as the transition is started, but before it ends. In addition, a method call on a transitioning component will be ignored. Learn more in our JavaScript docs.
方法 | 描述 |
---|---|
disable | 移除了元素弹出窗口的显示功能。只有重新启用弹出窗口后才能显示。 |
dispose | 隐藏和销毁元素的弹出窗口(删除 DOM 元素上存储的数据)。使用委托的弹出框(使用 selector 选项 创建)不能在后代触发元素上单独销毁。 |
enable | 使元素的弹出窗口能够显示。弹出窗口默认启用。 |
getInstance | 静态方法,允许你获取与 DOM 元素关联的 popover 实例。 |
getOrCreateInstance | 静态方法,允许你获取与 DOM 元素关联的 popover 实例,或者在它未初始化的情况下创建一个新的实例。 |
hide | 隐藏元素的弹出窗口。在弹出窗口实际隐藏之前(即 hidden.bs.popover 事件发生之前)返回给调用者。这被视为“手动”触发弹出窗口。 |
setContent | 提供一种在弹出窗口初始化后更改其内容的方法。 |
show | 显示元素的弹出窗口。在弹出窗口实际显示之前(即 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
。
¥The setContent
method accepts an object
argument, where each property-key is a valid string
selector within the popover template, and each related property-value can be string
| element
| function
| null
活动
¥Events
事件 | 描述 |
---|---|
hide.bs.popover | 调用 hide 实例方法后,此事件立即触发。 |
hidden.bs.popover | 当弹出窗口完全对用户隐藏时,会触发此事件(将等待 CSS 过渡完成)。 |
inserted.bs.popover | 当弹出窗口模板添加到 DOM 时,此事件在 show.bs.popover 事件之后触发。 |
show.bs.popover | 此事件在调用 show 实例方法时立即触发。 |
shown.bs.popover | 当弹出窗口对用户可见时,会触发此事件(将等待 CSS 过渡完成)。 |
const myPopoverTrigger = document.getElementById('myPopover')
myPopoverTrigger.addEventListener('hidden.bs.popover', () => {
// do something...
})