ion-modal
模態是一個顯示在應用程式內容頂部的對話方塊,必須由應用程式關閉才能恢復互動。當有許多選項可供選擇,或在清單中篩選項目時,以及許多其他用例中,它作為一個選取元件非常有用。
內嵌模態(建議使用)
ion-modal
可以通過直接在您的範本中編寫元件來使用。這減少了您需要連線以呈現模態的處理程式數量。
當使用 ion-modal
與 Angular、React 或 Vue 時,您傳入的元件將在模態關閉時被銷毀。由於此功能由 JavaScript 框架提供,因此在沒有 JavaScript 框架的情況下使用 ion-modal
將不會銷毀您傳入的元件。如果這是需要的功能,我們建議改用 modalController
。
使用 isOpen
ion-modal
上的 isOpen
屬性允許開發人員從其應用程式狀態控制模態的呈現狀態。這意味著當 isOpen
設定為 true
時,將呈現模態,而當 isOpen
設定為 false
時,將關閉模態。
isOpen
使用單向資料繫結,這意味著當模態關閉時,它不會自動設定為 false
。開發人員應監聽 ionModalDidDismiss
或 didDismiss
事件,並將 isOpen
設定為 false
。這樣做的原因是它可以防止 ion-modal
的內部結構與應用程式的狀態緊密耦合。通過單向資料繫結,模態只需要關注反應式變數提供的布林值。通過雙向資料繫結,模態需要關注布林值以及反應式變數本身的存在。這可能會導致不確定的行為,並使應用程式更難以偵錯。
控制器模態
使用 modalController
,開發人員可以以程式方式呈現 ion-modal
。開發人員將完全控制模態的呈現和關閉時間。
防止模態關閉
當在模態中輸入資料時,通常需要有一種方法來防止意外的資料遺失。ion-modal
上的 canDismiss
屬性讓開發人員可以控制何時允許關閉模態。
有兩種不同的方法可以使用 canDismiss
屬性:設定布林值或設定回呼函式。
注意:當使用表單模態時,如果沒有設定 0
斷點,則在滑動時不會檢查 canDismiss
。但是,當按下 Esc
或硬體返回按鈕時,仍會檢查它。
設定布林值
開發人員可以將 canDismiss
設定為布林值。如果 canDismiss
為 true
,則當使用者嘗試關閉模態時,模態將關閉。如果 canDismiss
為 false
,則當使用者嘗試關閉模態時,模態將不會關閉。
當您需要在關閉模態之前要求採取特定動作時,應使用設定布林值。例如,如果開發人員希望在關閉模態之前要求勾選「使用條款」核取方塊,他們可以將 canDismiss
初始設定為 false
,並在勾選核取方塊時將其更新為 true
。
設定回呼函式
開發人員可以將 canDismiss
設定為函式。此函式必須傳回解析為 true
或 false
的 Promise
。如果 promise 解析為 true
,則模態將關閉。如果 promise 解析為 false
,則模態將不會關閉。
當您具有複雜的關閉條件時,例如在關閉模態之前顯示確認對話方塊,應使用設定回呼函式。然後可以使用使用者在此對話方塊中選擇的選項來確定模態是否應繼續關閉。
請注意,當使用卡片或表單模態時,設定回呼函式將導致滑動手勢被中斷。這是因為 Ionic 不知道您的回呼函式將提前解析為哪個值。
防止滑動關閉
開發人員可能希望防止使用者滑動關閉卡片或表單模態。這可以通過為 canDismiss
設定回呼函式並檢查 role
是否不是 gesture
來完成。
在子元件中修改關閉行為
在某些情況下,開發人員可能需要根據呈現模態的狀態自訂 canDismiss
回呼的行為。當開發人員希望防止模態在其內部的表單無效時被關閉時,此自訂可能特別有用。
為了實現此自訂,子元件可以採用各種技術,例如函式回呼、事件發射或其他反應機制,以便與父元件通信並更新控制 canDismiss
回呼的條件。
以下是一個簡化的範例,說明子元件如何與父元件互動以修改 canDismiss
回呼
卡片模態
開發人員可以建立卡片模態效果,其中模態會顯示為堆疊在您的應用程式主要內容頂部的卡片。要建立卡片模態,開發人員需要在 ion-modal
上設定 presentingElement
屬性。
presentingElement
屬性接受應該在您的模態下方顯示的元素的參考。這通常是對 ion-router-outlet
的參考。
canDismiss
屬性可用於控制是否可以滑動關閉卡片模態。
卡片顯示樣式僅適用於 iOS。
工作表模式 (Sheet Modal)
如果您希望您的模式內容可以滾動,則應在工作表模式內使用內容。
開發人員可以建立類似於地圖應用程式中可用的抽屜元件的工作表模式效果。要建立工作表模式,開發人員需要在ion-modal
上設定breakpoints
和initialBreakpoint
屬性。
breakpoints
屬性接受一個陣列,其中聲明了工作表在滑動時可以捕捉到的每個斷點。breakpoints
屬性為[0, 0.5, 1]
表示工作表可以滑動以顯示模式的 0%、50% 和 100%。當模式滑動到 0% 時,模式將會自動關閉。請注意,如果未包含 0
斷點,則無法透過滑動關閉模式,但仍然可以透過按 Esc
鍵或硬體返回按鈕關閉。
需要initialBreakpoint
屬性,以便工作表模式知道在呈現時從哪個斷點開始。initialBreakpoint
值也必須存在於breakpoints
陣列中。給定breakpoints
的值為[0, 0.5, 1]
,則initialBreakpoint
的值為0.5
是有效的,因為0.5
在breakpoints
陣列中。initialBreakpoint
的值為0.25
將無效,因為0.25
不存在於breakpoints
陣列中。
backdropBreakpoint
屬性可用於自訂ion-backdrop
開始淡入的點。當建立在工作表下方具有應保持互動內容的介面時,這非常有用。一個常見的使用案例是覆蓋地圖的工作表模式,其中地圖在工作表完全展開之前是互動式的。
與背景內容互動
自訂工作表高度
開發人員應使用--height
CSS 變數來變更工作表模式的高度,而不是變更breakpoints
陣列中的最後一個斷點。這樣做的原因是將breakpoints
陣列中的最後一個斷點變更為小於1
的值,將導致模式的部分內容無法在視窗外存取。
以下範例展示如何取得根據其內容自動調整大小的工作表模式。請注意,透過將最大斷點保持在1
,我們確保整個模式都可以在視窗中存取。
控制代碼行為
工作表模式可以選擇性地呈現用於在斷點之間拖曳工作表的控制代碼指示器。handleBehavior
屬性可用於設定使用者啟用控制代碼時的行為。
樣式設定
模式會顯示在您應用程式的根目錄,因此它們會覆蓋您的整個應用程式。此行為適用於內嵌模式和從控制器呈現的模式。因此,自訂模式樣式不能限定於特定的元件,因為它們不會應用於模式。相反,樣式必須全域應用。對於大多數開發人員來說,將自訂樣式放置在global.css
中就足夠了。
如果您正在建置 Ionic Angular 應用程式,則需要將樣式新增至全域樣式表檔案中。有關更多資訊,請閱讀下面的 Angular 章節中的樣式放置。
ion-modal
假設堆疊的模式大小相同。因此,每個後續的模式將沒有陰影,並且背景不透明度為0
。這是為了避免陰影和背景隨著每個新增的模式而變得更暗的效果。可以透過設定--box-shadow
和--backdrop-opacity
CSS 變數來變更此設定
ion-modal.stack-modal {
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
動畫
可以使用我們的動畫建置器自訂進入和離開動畫,並將動畫分配給enterAnimation
和leaveAnimation
。
自訂對話框
雖然ion-modal
最常用於全頁檢視、卡片或工作表,但也可以將其用於自訂對話框。如果開發人員需要比ion-alert或ion-loading等元件提供的介面更複雜的介面,這非常有用。
建立自訂對話框時需要記住一些事項
ion-content
旨在用於全頁模式、卡片和工作表中。如果您的自訂對話框具有動態或未知大小,則不應使用ion-content
。- 建立自訂對話框提供了一種從預設模式體驗中退出的方法。因此,自訂對話框不應與卡片或工作表模式一起使用。
介面
ModalOptions
以下是您在使用modalController
時可用的所有選項。呼叫modalController.create()
時應提供這些選項。
interface ModalOptions {
component: any;
componentProps?: { [key: string]: any };
presentingElement?: HTMLElement;
showBackdrop?: boolean;
backdropDismiss?: boolean;
cssClass?: string | string[];
animated?: boolean;
canDismiss?: boolean | ((data?: any, role?: string) => Promise<boolean>);
mode?: 'ios' | 'md';
keyboardClose?: boolean;
id?: string;
htmlAttributes?: { [key: string]: any };
enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
breakpoints?: number[];
initialBreakpoint?: number;
backdropBreakpoint?: number;
handle?: boolean;
}
ModalCustomEvent
雖然不是必需的,但此介面可用於取代CustomEvent
介面,以便使用此元件發出的 Ionic 事件進行更強的類型檢查。
interface ModalCustomEvent extends CustomEvent {
target: HTMLIonModalElement;
}
輔助功能
鍵盤互動
按鍵 | 描述 |
---|---|
Esc | 關閉模式 |
標籤
模式具有dialog
角色。因此,開發人員必須正確標記他們的模式。如果模式使用ion-title
,則可以透過在ion-modal
上設定aria-labelledby
來使用內部文字標記模式本身。如果模式包含其他描述性文字,則可以使用aria-describedby
將此文字與模式相關聯。
螢幕閱讀器
模式已應用aria-modal
屬性。此屬性可能會導致輔助技術將導覽限制為模式元素的內容。因此,使用移動到下一個或上一個項目的手勢可能不會將焦點放在模式外部的元素上。即使在使用backdropBreakpoint
屬性的工作表模式中停用背景時,也是如此。
如果開發人員手動移動焦點,則輔助技術不會將導覽限制為模式元素的內容。但是,對於啟用焦點陷阱的模式,Ionic 不支援在模式外部手動移動焦點。
有關更多資訊,請參閱https://w3c.github.io/aria/#aria-modal。
焦點陷阱
呈現模式時,焦點將被困在呈現的模式內。使用者可以將焦點放在模式內的其他互動元素上,但在呈現模式時永遠無法將焦點放在模式外的互動元素上。對於呈現多個堆疊模式的應用程式,焦點將被困在最後呈現的模式上。
透過backdropBreakpoint
屬性停用背景的工作表模式不受焦點陷阱的影響。
工作表模式
當使用backdropBreakpoint
屬性時,工作表模式允許使用者與模式後方的內容互動。背景將被停用到指定的backdropBreakpoint
(包括此點),並在此點之後啟用。
當停用背景時,使用者將能夠使用指標或鍵盤與工作表模式外的元素互動。由於使用了aria-modal
,輔助技術可能預設不會將焦點放在工作表模式外。我們建議避免使用自動對焦等功能,因為它可能會導致輔助技術在兩個互動式內容之間跳轉,而沒有警告使用者。
效能
掛載內部內容
關閉時,內嵌ion-modal
的內容將被卸載。如果此內容的渲染成本很高,開發人員可以使用keepContentsMounted
屬性在掛載模式後立即掛載內容。這有助於優化應用程式的響應速度,因為內部內容將在模式開啟時已被掛載。
使用keepContentsMounted
時,開發人員應注意以下事項
-
此功能應作為最後的手段使用,以解決現有的效能問題。在使用此功能之前,請嘗試識別並解決效能瓶頸。此外,不要使用此功能來預期效能問題。
-
僅當使用 JavaScript 框架時才需要此功能。未使用框架的開發人員可以將要呈現的內容傳遞到模式中,並且這些內容將會自動呈現。
-
此功能僅適用於內嵌模式。使用
modalController
建立的模式不是提前建立的,因此也不會建立內部內容。 -
內部元件上的任何 JavaScript 框架生命週期掛鉤都會在掛載模式後立即執行,而不是在呈現模式時執行。
屬性
animated
描述 | 如果為true ,則模式將會產生動畫。 |
屬性 | animated |
類型 | boolean |
預設值 | true |
backdropBreakpoint
描述 | 介於 0 和 1 之間的小數值,表示使用工作表模式時,背景將開始淡入的點。在此點之前,背景將被隱藏,並且可以與工作表下方的內容互動。此值是互斥的,表示背景將在指定值之後變為啟用狀態。 |
屬性 | backdrop-breakpoint |
類型 | number |
預設值 | 0 |
backdropDismiss
描述 | 如果為true ,則在點擊背景時,模式將會被關閉。 |
屬性 | backdrop-dismiss |
類型 | boolean |
預設值 | true |
breakpoints
描述 | 建立工作表模式時要使用的斷點。陣列中的每個值都必須是介於 0 和 1 之間的小數,其中 0 表示模式完全關閉,1 表示模式完全開啟。這些值相對於模式的高度,而不是螢幕的高度。此陣列中的其中一個值必須是initialBreakpoint 屬性的值。例如:[0, .25, .5, 1] |
屬性 | undefined |
類型 | number[] | undefined |
預設值 | undefined |
canDismiss
描述 | 決定在呼叫 dismiss 方法時,是否可以關閉模態視窗。如果值為 true 或該值的函式回傳 true ,則在嘗試關閉時,模態視窗將會關閉。如果值為 false 或該值的函式回傳 false ,則在嘗試關閉時,模態視窗將不會關閉。如果您需要從回呼函式中存取 this ,請參閱 https://ionic.dev.org.tw/docs/troubleshooting/runtime#accessing-this。 |
屬性 | can-dismiss |
類型 | ((data?: any, role?: string | undefined) => Promise<boolean>) | boolean |
預設值 | true |
enterAnimation
描述 | 當模態視窗呈現時要使用的動畫。 |
屬性 | undefined |
類型 | ((baseEl: any, opts?: any) => Animation) | undefined |
預設值 | undefined |
focusTrap
描述 | 如果為 true ,焦點將不允許移動到此覆蓋層之外。如果為 false ,焦點將允許移動到覆蓋層之外。在大多數情況下,此屬性應保持設定為 true 。將此屬性設定為 false 可能會導致嚴重的輔助功能問題,因為依賴輔助技術的使用者可能會將焦點移至混亂的狀態。我們建議僅在絕對必要時才將此設定為 false 。開發人員可能需要考慮在從第三方函式庫呈現非 Ionic 覆蓋層時停用焦點捕獲。開發人員會在呈現第三方覆蓋層時停用 Ionic 覆蓋層上的焦點捕獲,然後在關閉第三方覆蓋層並將焦點移回 Ionic 覆蓋層時重新啟用焦點捕獲。 |
屬性 | focus-trap |
類型 | boolean |
預設值 | true |
handle
描述 | 在工作表模態視窗頂部顯示的水平線。當設定 breakpoints 和 initialBreakpoint 屬性時,預設為 true 。 |
屬性 | handle |
類型 | boolean | undefined |
預設值 | undefined |
handleBehavior
描述 | 按下控制點時,工作表模態視窗的互動行為。 預設值為 "none" ,表示按下控制點時,模態視窗的大小或位置不會改變。設定為 "cycle" 讓模態視窗在按下時於可用的斷點之間循環。當 handle 屬性設定為 false 或未設定 breakpoints 屬性時(使用全螢幕或卡片模態視窗),控制點行為不可用。 |
屬性 | handle-behavior |
類型 | "cycle" | "none" | undefined |
預設值 | 'none' |
htmlAttributes
描述 | 要傳遞給模態視窗的其他屬性。 |
屬性 | undefined |
類型 | undefined | { [key: string]: any; } |
預設值 | undefined |
initialBreakpoint
描述 | 一個介於 0 和 1 之間的十進制值,表示建立工作表模態視窗時模態視窗開啟的初始點。此值也必須列在 breakpoints 陣列中。 |
屬性 | initial-breakpoint |
類型 | number | undefined |
預設值 | undefined |
isOpen
描述 | 如果為 true ,模態視窗將會開啟。如果為 false ,模態視窗將會關閉。如果您需要更精細地控制呈現,請使用此項,否則請使用 modalController 或 trigger 屬性。注意:當模態視窗關閉時,isOpen 不會自動設定回 false 。您需要在程式碼中執行此操作。 |
屬性 | is-open |
類型 | boolean |
預設值 | false |
keepContentsMounted
描述 | 如果為 true ,則當建立模態視窗時,傳遞到 ion-modal 的元件會自動掛載。即使在關閉模態視窗後,該元件仍會保持掛載。但是,當模態視窗銷毀時,該元件也會被銷毀。此屬性不具反應性,應僅在初始建立模態視窗時使用。注意:此功能僅適用於 JavaScript 框架(例如 Angular、React 和 Vue)中的內嵌模態視窗。 |
屬性 | keep-contents-mounted |
類型 | boolean |
預設值 | false |
keyboardClose
描述 | 如果為 true ,則在呈現覆蓋層時會自動關閉鍵盤。 |
屬性 | keyboard-close |
類型 | boolean |
預設值 | true |
leaveAnimation
描述 | 當關閉模態視窗時要使用的動畫。 |
屬性 | undefined |
類型 | ((baseEl: any, opts?: any) => Animation) | undefined |
預設值 | undefined |
mode
描述 | 模式決定要使用哪個平台的樣式。 |
屬性 | mode |
類型 | "ios" | "md" |
預設值 | undefined |
presentingElement
描述 | 呈現模態視窗的元素。這用於卡片呈現效果,以及將多個模態視窗堆疊在彼此之上。僅適用於 iOS 模式。 |
屬性 | undefined |
類型 | HTMLElement | undefined |
預設值 | undefined |
showBackdrop
描述 | 如果為 true ,模態視窗後面將會顯示背景幕。此屬性控制在呈現模態視窗時,背景幕是否會使螢幕變暗。它不控制背景幕是否在 DOM 中處於活動狀態或呈現狀態。 |
屬性 | show-backdrop |
類型 | boolean |
預設值 | true |
trigger
描述 | 對應於觸發元素的 ID,該元素在點擊時會導致模態視窗開啟。 |
屬性 | trigger |
類型 | string | undefined |
預設值 | undefined |
Events
名稱 | 描述 | 冒泡 |
---|---|---|
didDismiss | 在關閉模態視窗後發出。是 ionModalDidDismiss 的簡寫。 | true |
didPresent | 在呈現模態視窗後發出。是 ionModalDidPresent 的簡寫。 | true |
ionBreakpointDidChange | 在模態視窗斷點變更後發出。 | true |
ionModalDidDismiss | 在關閉模態視窗後發出。 | true |
ionModalDidPresent | 在呈現模態視窗後發出。 | true |
ionModalWillDismiss | 在關閉模態視窗之前發出。 | true |
ionModalWillPresent | 在呈現模態視窗之前發出。 | true |
willDismiss | 在關閉模態視窗之前發出。是 ionModalWillDismiss 的簡寫。 | true |
willPresent | 在呈現模態視窗之前發出。是 ionModalWillPresent 的簡寫。 | true |
Methods
dismiss
描述 | 在呈現模態視窗後關閉該視窗。 |
簽名 | dismiss(data?: any, role?: string) => Promise<boolean> |
getCurrentBreakpoint
描述 | 傳回工作表樣式模態視窗的目前斷點。 |
簽名 | getCurrentBreakpoint() => Promise<number | undefined> |
onDidDismiss
描述 | 傳回當模態視窗關閉時解析的 Promise。 |
簽名 | onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
onWillDismiss
描述 | 傳回當模態視窗將要關閉時解析的 Promise。 |
簽名 | onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
present
描述 | 在建立模態視窗後呈現該視窗。 |
簽名 | present() => Promise<void> |
setCurrentBreakpoint
描述 | 將工作表樣式模態視窗移動到特定的斷點。斷點值必須是您 breakpoints 陣列中定義的值。 |
簽名 | setCurrentBreakpoint(breakpoint: number) => Promise<void> |
CSS Shadow Parts
名稱 | 描述 |
---|---|
backdrop | ion-backdrop 元素。 |
content | 預設插槽的包裝元素。 |
handle | 當 handle="true" 時,顯示在工作表模態視窗頂部的控制點。 |
CSS Custom Properties
- iOS
- MD
名稱 | 描述 |
---|---|
--backdrop-opacity | 背景幕的不透明度 |
--background | 模態視窗內容的背景 |
--border-color | 模態視窗內容的邊框顏色 |
--border-radius | 模態視窗內容的邊框半徑 |
--border-style | 模態視窗內容的邊框樣式 |
--border-width | 模態視窗內容的邊框寬度 |
--height | 模態視窗的高度 |
--max-height | 模態視窗的最大高度 |
--max-width | 模態視窗的最大寬度 |
--min-height | 模態視窗的最小高度 |
--min-width | 模態視窗的最小寬度 |
--width | 模態視窗的寬度 |
名稱 | 描述 |
---|---|
--backdrop-opacity | 背景幕的不透明度 |
--background | 模態視窗內容的背景 |
--border-color | 模態視窗內容的邊框顏色 |
--border-radius | 模態視窗內容的邊框半徑 |
--border-style | 模態視窗內容的邊框樣式 |
--border-width | 模態視窗內容的邊框寬度 |
--height | 模態視窗的高度 |
--max-height | 模態視窗的最大高度 |
--max-width | 模態視窗的最大寬度 |
--min-height | 模態視窗的最小高度 |
--min-width | 模態視窗的最小寬度 |
--width | 模態視窗的寬度 |
Slots
名稱 | 描述 |
---|---|
`` | 內容會放置在 .modal-content 元素內。 |