ion-popover
Popover 是一个出现在当前页面顶部的对话框。它可以用于任何用途,但通常用于那些在导航栏中无法容纳的溢出操作。
🌐 A Popover is a dialog that appears on top of the current page. It can be used for anything, but generally it is used for overflow actions that don't fit in the navigation bar.
使用 ion-popover 有两种方法:内联使用或通过 popoverController 使用。每种方法都有不同的注意事项,因此请确保使用最适合你使用场景的方法。
🌐 There are two ways to use ion-popover: inline or via the popoverController. Each method comes with different considerations, so be sure to use the approach that best fits your use case.
内联弹出窗口
🌐 Inline Popovers
ion-popover 可以通过直接在你的模板中编写组件来使用。这减少了你为展示弹出框所需连接的处理程序数量。
在将 ion-popover 与 Angular、React 或 Vue 一起使用时,当弹出框被关闭时,你传入的组件将会被销毁。由于此功能是由 JavaScript 框架提供的,因此在没有 JavaScript 框架的情况下使用 ion-popover 不会销毁你传入的组件。如果这是一个必要的功能,我们建议使用 popoverController。
🌐 When using ion-popover with Angular, React, or Vue, the component you pass in will be destroyed when the popover is dismissed. As this functionality is provided by the JavaScript framework, using ion-popover without a JavaScript framework will not destroy the component you passed in. If this is a needed functionality, we recommend using the popoverController instead.
何时使用
🌐 When to use
在内联中使用弹出框是有用的,当你不想显式地绑定点击事件来打开弹出框时。例如,你可以使用 trigger 属性来指定一个按钮,当点击时应该显示弹出框。你还可以使用 trigger-action 属性来自定义弹出框在触发器被左击、右击或悬停时是否应该显示。
🌐 Using a popover inline is useful when you do not want to explicitly wire up click events to open the popover. For example, you can use the trigger property to designate a button that should present the popover when clicked. You can also use the trigger-action property to customize whether the popover should be presented when the trigger is left clicked, right clicked, or hovered over.
如果你需要对弹出窗口何时显示和关闭进行细粒度控制,我们建议你使用 popoverController。
🌐 If you need fine grained control over when the popover is presented and dismissed, we recommend you use the popoverController.
Angular
由于你传入的组件需要在弹出框显示时创建,并在弹出框关闭时销毁,我们无法在内部使用 <ng-content> 来投影内容。相反,我们使用 <ng-container>,它需要传入一个 <ng-template>。因此,在传入你的组件时,你需要将其封装在一个 <ng-template> 中:
🌐 Since the component you passed in needs to be created when the popover is presented and destroyed when the popover is dismissed, we are unable to project the content using <ng-content> internally. Instead, we use <ng-container> which expects an <ng-template> to be passed in. As a result, when passing in your component you will need to wrap it in an <ng-template>:
<ion-popover [isOpen]="isPopoverOpen">
<ng-template>
<app-popover-content></app-popover-content>
</ng-template>
</ion-popover>
触发器
🌐 Triggers
内联 ion-popover 的触发器是与之交互时将打开弹出框的元素。可以通过设置 trigger-action 属性来自定义交互行为。请注意,trigger-action="context-menu" 将阻止系统默认的上下文菜单打开。
🌐 A trigger for an inline ion-popover is the element that will open a popover when interacted with. The interaction behavior can be customized by setting the trigger-action property. Note that trigger-action="context-menu" will prevent your system's default context menu from opening.
在使用 popoverController 时触发器不适用,因为 ion-popover 并未提前创建。
isOpen 属性
🌐 isOpen Property
内联弹出层也可以通过将 isOpen 属性设置为 true 来打开。如果你需要比使用触发器更精细地控制弹出层,则可以使用此方法。
🌐 Inline popovers can also be opened by setting the isOpen property to true. This method can be used if you need finer grained control over the popover than with a trigger.
isOpen 使用单向数据绑定,这意味着在弹出框被关闭时,它不会自动设置为 false。开发者应该监听 ionPopoverDidDismiss 或 didDismiss 事件,并将 isOpen 设置为 false。这样做的原因是为了防止 ion-popover 的内部实现与应用的状态紧密耦合。使用单向数据绑定时,弹出框只需要关心响应式变量提供的布尔值。使用双向数据绑定时,弹出框需要同时关心布尔值以及响应式变量本身的存在。这可能导致不确定的行为,并使应用更难调试。
控制器弹出窗口
🌐 Controller Popovers
ion-popover 也可以通过使用从 Ionic Framework 导入的 popoverController 以编程方式渲染。这使你能够在弹出框显示时拥有完全的控制,超越内联弹出框所提供的自定义功能。
何时使用
🌐 When to use
我们通常建议你将弹出框内联编写,因为这可以简化应用中的代码量。你只有在编写内联弹出框不切实际的复杂用例中才使用 popoverController。使用控制器时,你的弹出框不会提前创建,因此像 trigger 和 trigger-action 这样的属性在这里不适用。此外,嵌套弹出框与控制器方法不兼容,因为调用 create 方法时,弹出框会自动添加到应用的根节点。
🌐 We typically recommend that you write your popovers inline as it streamlines the amount of code in your application. You should only use the popoverController for complex use cases where writing a popover inline is impractical. When using a controller, your popover is not created ahead of time, so properties such as trigger and trigger-action are not applicable here. In addition, nested popovers are not compatible with the controller approach because the popover is automatically added to the root of your application when the create method is called.
React
React 有一个名为 useIonPopover 的钩子,它的行为类似于控制器。请注意,useIonPopover 需要是 <IonApp> 的子孙。如果你需要在 <IonApp> 之外使用弹出框,考虑使用内联弹出框。
🌐 Instead of a controller, React has a hook called useIonPopover which behaves in a similar fashion. Note that useIonPopover requires being a descendant of <IonApp>. If you need to use a popover outside of an <IonApp>, consider using an inline popover instead.
用法
🌐 Usage
ConsoleConsole messages will appear here when logged from the example above.样式
🌐 Styling
弹出框显示在应用的根部,因此它们会覆盖整个应用。此行为适用于内联弹出框以及从控制器渲染的弹出框。因此,自定义弹出框样式不能限定于特定组件,因为它们不会应用于弹出框。相反,样式必须全局应用。对于大多数开发者来说,将自定义样式放置在 global.css 中就足够了。
🌐 Popovers are presented at the root of your application so they overlay your entire app. This behavior applies to both inline popovers and popovers presented from a controller. As a result, custom popover styles can not be scoped to a particular component as they will not apply to the popover. Instead, styles must be applied globally. For most developers, placing the custom styles in global.css is sufficient.
如果你正在构建 Ionic Angular 应用,则需要将样式添加到全局样式表文件中。
定位
🌐 Positioning
参考
🌐 Reference
在显示弹出框时,Ionic 框架需要一个参考点来相对于该点显示弹出框。使用 reference="event" 时,弹出框将相对于在触发元素上分发的指针事件的 x-y 坐标显示。使用 reference="trigger" 时,弹出框将相对于触发元素的边界框显示。
🌐 When presenting a popover, Ionic Framework needs a reference point to present the popover relative to. With reference="event", the popover will be presented relative to the x-y coordinates of the pointer event that was dispatched on your trigger element. With reference="trigger", the popover will be presented relative to the bounding box of your trigger element.
端
🌐 Side
无论你为参考点选择什么,你都可以使用 side 属性将弹出框定位在参考点的 top、right、left 或 bottom。如果你希望侧边根据从左到右或从右到左模式切换,也可以使用 start 或 end 值。
🌐 Regardless of what you choose for your reference point, you can position a popover to the top, right, left, or bottom of your reference point by using the side property. You can also use the start or end values if you would like the side to switch based on LTR or RTL modes.
对齐
🌐 Alignment
alignment 属性允许你将弹出框的一条边与触发元素的对应边对齐。具体使用哪一条边取决于 side 属性的值。
🌐 The alignment property allows you to line up an edge of your popover with a corresponding edge on your trigger element. The exact edge that is used depends on the value of the side property.
侧面和对齐演示
🌐 Side and Alignment Demo
偏移量
🌐 Offsets
如果你需要对弹出框的位置进行更精细的控制,你可以使用 --offset-x 和 --offset-y CSS 变量。例如,--offset-x: 10px 会将你的弹出框内容向右移动 10px。
🌐 If you need finer grained control over the positioning of your popover you can use the --offset-x and --offset-y CSS Variables. For example, --offset-x: 10px will move your popover content to the right by 10px.
尺寸
🌐 Sizing
在制作下拉菜单时,你可能希望弹出菜单的宽度与触发元素的宽度匹配。如果事先不知道触发元素的宽度,这会比较棘手。你可以将 size 属性设置为 'cover',Ionic 框架将确保弹出菜单的宽度与你的触发元素宽度匹配。
🌐 When making dropdown menus, you may want to have the width of the popover match the width of the trigger element. Doing this without knowing the trigger width ahead of time is tricky. You can set the size property to 'cover' and Ionic Framework will ensure that the width of the popover matches the width of your trigger element.
如果你正在使用 popoverController,你必须通过 event 选项提供一个事件,并且 Ionic Framework 将使用 event.target 作为参考元素。有关此模式的示例,请参见 controller demo。
🌐 If you are using the popoverController, you must provide an event via the event option and Ionic Framework will use event.target as the reference element. See the controller demo for an example of this pattern.
嵌套弹出窗口
🌐 Nested Popovers
在使用 ion-popover 内联时,你可以嵌套弹出框以创建嵌套下拉菜单。这样做时,只有第一个弹出框的背景会出现,以避免打开更多弹出框时屏幕逐渐变暗。
🌐 When using ion-popover inline, you can nested popovers to create nested dropdown menus. When doing this, only the backdrop on the first popover will appear so that the screen does not get progressively darker as you open more popovers.
你可以使用 dismissOnSelect 属性在点击弹出内容时自动关闭弹出框。此行为在点击另一个弹出框的触发元素时不适用。
🌐 You can use the dismissOnSelect property to automatically close the popover when the popover content has been clicked. This behavior does not apply when clicking a trigger element for another popover.
使用 popoverController 时无法创建嵌套弹出框,因为当调用 create 方法时,弹出框会自动添加到应用的根节点。
接口
🌐 Interfaces
下面你将找到使用 popoverController 时可用的所有选项。这些选项应在调用 popoverController.create() 时提供。
🌐 Below you will find all of the options available to you when using the popoverController. These options should be supplied when calling popoverController.create().
interface PopoverOptions {
component: any;
componentProps?: { [key: string]: any };
showBackdrop?: boolean;
backdropDismiss?: boolean;
translucent?: boolean;
cssClass?: string | string[];
event?: Event;
animated?: boolean;
mode?: 'ios' | 'md';
keyboardClose?: boolean;
id?: string;
htmlAttributes?: { [key: string]: any };
enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
size?: PopoverSize;
dismissOnSelect?: boolean;
reference?: PositionReference;
side?: PositionSide;
alignment?: PositionAlign;
arrow?: boolean;
}
类型
🌐 Types
下面你将找到 ion-popover 的所有自定义类型:
🌐 Below you will find all of the custom types for ion-popover:
type PopoverSize = 'cover' | 'auto';
type TriggerAction = 'click' | 'hover' | 'context-menu';
type PositionReference = 'trigger' | 'event';
type PositionSide = 'top' | 'right' | 'bottom' | 'left' | 'start' | 'end';
type PositionAlign = 'start' | 'center' | 'end';
无障碍
🌐 Accessibility
键盘交互
🌐 Keyboard Interactions
ion-popover 对在弹出框内导航可聚焦元素提供基本的键盘支持。下表详细说明了每个键的功能:
| 键 | 描述 |
|---|---|
| Tab | 将焦点移到下一个可聚焦元素。 |
| Shift + Tab | 将焦点移到上一个可聚焦元素。 |
| Esc | 关闭弹出框。 |
| Space 或 Enter | 点击可聚焦元素。 |
ion-popover 完全支持使用箭头键在具有 button 属性的 ion-item 元素之间导航。最常见的用例是在面向桌面的应用中作为下拉菜单使用。除了基本的键盘支持外,下面的表格还详细说明了下拉菜单的箭头键支持情况:
| 键 | 描述 |
|---|---|
| ArrowUp | 将焦点移至上一个可聚焦元素。 |
| ArrowDown | 将焦点移至下一个可聚焦元素。 |
| Home | 将焦点移至第一个可聚焦元素。 |
| End | 将焦点移至最后一个可聚焦元素。 |
| ArrowLeft | 在子弹出框中使用时,关闭弹出框并将焦点返回父弹出框。 |
| Space, Enter 和 ArrowRight | 在聚焦触发元素时,打开关联的弹出框 。 |
性能
🌐 Performance
挂载内部内容
🌐 Mounting Inner Contents
当关闭时,内联 ion-popover 的内容会被卸载。如果这些内容的渲染成本很高,开发者可以使用 keepContentsMounted 属性在弹出框挂载时立即挂载内容。这可以帮助优化应用的响应速度,因为当弹出框打开时,内部内容已经被挂载。
🌐 The content of an inline ion-popover is unmounted when closed. If this content is expensive to render, developers can use the keepContentsMounted property to mount the content as soon as the popover is mounted. This can help optimize the responsiveness of your application as the inner contents will have already been mounted when the popover opens.
开发者在使用 keepContentsMounted 时应记住以下几点:
🌐 Developers should keep the following in mind when using keepContentsMounted:
- 此功能应作为应对现有性能问题的最后手段。在使用此功能之前,尝试识别并解决性能瓶颈。此外,不要使用此功能来预判性能问题。
- 此功能仅在使用 JavaScript 框架时需要。不使用框架的开发者可以将要渲染的内容传递到弹出框中,内容将自动渲染。
- 此功能仅适用于内联弹出框。使用
popoverController创建的弹出框不会提前创建,因此其内部内容也不会被创建。 - 内部组件上的任何 JavaScript 框架生命周期钩子都会在弹出窗口安装后立即运行,而不是在弹出窗口显示时运行。
属性
🌐 Properties
alignment
| Description | Describes how to align the popover content with the reference point. Defaults to "center" for ios mode, and "start" for md mode. |
| Attribute | alignment |
| Type | "center" | "end" | "start" | undefined |
| Default | undefined |
animated
| Description | If true, the popover will animate. |
| Attribute | animated |
| Type | boolean |
| Default | true |
arrow
| Description | If true, the popover will display an arrow that points at the reference when running in ios mode. Does not apply in md mode. |
| Attribute | arrow |
| Type | boolean |
| Default | true |
backdropDismiss
| Description | If true, the popover will be dismissed when the backdrop is clicked. |
| Attribute | backdrop-dismiss |
| Type | boolean |
| Default | true |