自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你可能不知道的Dialog彈窗

開發(fā) 前端
dialog其實(shí)我在兩三年之前就有研究過(guò),那時(shí)還沒(méi)有這么多新特性,也有可能是研究不精,后來(lái)就擱置了,然后最近在項(xiàng)目中用了dialog,無(wú)意中又發(fā)現(xiàn)了很多有意思的新特性,這意味著,dom 其實(shí)也是在不斷發(fā)展的,有必要把以前已經(jīng)用過(guò)的再翻出來(lái)過(guò)一遍,說(shuō)不定還能發(fā)現(xiàn)意想不到的結(jié)果。

除了有良好的語(yǔ)義外,隨著瀏覽器的不斷更新迭代,還出現(xiàn)了許多你可能不知道的特性,快速了解一下吧~

圖片

一、打開和關(guān)閉方法

首先,在不查閱任何官方文檔的情況下,先做一個(gè)選擇題目

請(qǐng)問(wèn):下面哪組方法(打開/關(guān)閉)是合法的?

圖片

思考 10 秒...

??

??

??

??

正確答案是 C,也就是

// 打開彈窗
dialog.show()
// 打開關(guān)閉
dialog.close()

很多同學(xué)可能會(huì)覺(jué)得是 A 或者 B,但是官方文檔上確是 C,確實(shí)是一個(gè)令人迷惑的方法。至于原因,有解釋說(shuō),dialog是存在于頁(yè)面上的元素,所以打開用show,而關(guān)閉表示中斷彈窗內(nèi)的行為,所以用close,只能說(shuō)有聯(lián)系,但比較牽強(qiáng),或許就是規(guī)范設(shè)計(jì)疏忽了,大家記住就好。

還有一個(gè),如果需要彈窗默認(rèn)顯示,大家先猜猜看?

圖片

再來(lái)思考 10 秒...

??

??

??

??

正確答案是 B,也就是

<dialog open></dialog>

??是不是又和上面的show()對(duì)不上了?

除了dialog元素,details元素的打開屬性也是open

二、表單提交特性

彈窗很多時(shí)候的作用都是充當(dāng)表單輸入。

比如一個(gè)彈窗中需要有一個(gè)關(guān)閉或者取消按鈕

<dialog>
<h3>歡迎關(guān)注前端偵探</h3>
<button>關(guān)閉</button>
</dialog>

通常情況下,我們可能需要用到前面提到的dialog.close()方法來(lái)主動(dòng)關(guān)閉彈窗。

其實(shí),還可以通過(guò)表單特性實(shí)現(xiàn)這樣一個(gè)效果,具體做法是:

  1. 在dialog中嵌套一層form
  2. 給form添加一個(gè)method=dialog屬性

如下

<dialog>
<form method="dialog">
<h3>歡迎關(guān)注前端偵探</h3>
<button>關(guān)閉</button>
</form>
</dialog>

這樣就可以不用綁定額外的事件來(lái)實(shí)現(xiàn)關(guān)閉功能了,效果如下

Kapture 2023-01-14 at 12.52.33

其實(shí)原因就在于表單上的method=dialog屬性,如果表單在dialog元素中,提交時(shí)就會(huì)觸發(fā)關(guān)閉對(duì)話框

https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/form#attr-method

默認(rèn)情況下,表單里的button都會(huì)觸發(fā)提交,等同于type=submit,但如果設(shè)置了type=button或者type=reset,則不會(huì)觸發(fā)表單提交,自然也不會(huì)關(guān)閉彈窗

<dialog>
<form method="dialog">
<h3>歡迎關(guān)注前端偵探</h3>
<button>關(guān)閉</button>
<button type="button">不會(huì)關(guān)閉</button>
</form>
</dialog>

效果如下

圖片

另外還有一個(gè)小特性,dialog還有一個(gè)returnValue屬性,可以返回表單中提交按鈕的value值

<dialog>
<form method="dialog">
<h3>歡迎關(guān)注前端偵探</h3>
<button value="AAA">提交</button>
</form>
</dialog>

在提交后可以打印彈窗的returnValue,如下

圖片

image-20230114132406007

不過(guò)暫時(shí)還沒(méi)有想到很有用的場(chǎng)景

三、模態(tài)窗口特性

彈窗除了可以通過(guò)dialog.show()打開之外,還提供了一個(gè)模態(tài)窗口,方法是

dailog.showModal()

通過(guò)這個(gè)方法打開的彈窗,會(huì)自帶一個(gè)半透明的背景,并且完全水平垂直居中

圖片

這個(gè)半透明的背景并不是普通的元素,而是一個(gè)叫做::backdrop[1]的偽元素控制的,并且目前只有通過(guò)dailog.showModal()這個(gè)方法才能生成

要自定義背景也很容易

dialog::backdrop {
background: rgba(255,0,0,.25);
}

這樣就變成了半透明紅色

圖片

如果希望打開彈窗有動(dòng)畫,可以自定義默認(rèn)樣式,通過(guò)visibility的方式實(shí)現(xiàn)隱藏顯示

dialog{
position: fixed;
margin: auto;
inset: 0;
width: fit-content;
height: fit-content;
display: block;
visibility: hidden;
opacity: 0;
transform: translateY(100px);
transition: .2s;
}
dialog[open] {
visibility: visible;
opacity: 1;
transform: translateY(0);
}

效果如下

圖片

其實(shí)這里我是不太建議動(dòng)畫的,彈窗就是要反應(yīng)快速,加了動(dòng)畫反而會(huì)拖累整體。

另外,還可以通過(guò):modal偽類來(lái)區(qū)分是普通彈窗還是模態(tài)彈窗

dialog:modal{
/*模態(tài)彈窗*/
}
dialog:not(:modal){
/*普通彈窗*/
}

這樣可以更多進(jìn)行自定義行為

模態(tài)彈窗還有一個(gè)非常省心的點(diǎn),就是無(wú)需關(guān)注層級(jí)。它有一套非常直觀的規(guī)則,哪個(gè)后打開,哪個(gè)層級(jí)最高,比如這樣兩個(gè)彈窗

<dialog id="dialog2">
...
</dialog>
<dialog id="dialog1">
...
<button type="button">打開彈窗2</button>
...
</dialog>

在不指定層級(jí)的情況下,肯定是后面的層級(jí)更高,但如果是通過(guò)dialog.showModal打開,就非常直觀了,后打開的彈窗肯定會(huì)覆蓋前面的,效果如下

圖片

說(shuō)到這里,我又想到了一些UI組件庫(kù)里大到可怕的z-index,大概率就是通過(guò)計(jì)算不斷疊加得出的

四、焦點(diǎn)隔離特性

除了上面一些比較直觀的特性外,還有一些可能會(huì)忽略的,比如焦點(diǎn)的控制。

默認(rèn)情況下,打開彈窗后會(huì)自動(dòng)聚焦到彈窗內(nèi)的第一個(gè)可聚焦元素上

Kapture 2023-01-14 at 14.34.43

還可以有input輸入框

<dialog>
<form method="dialog">
<h3>歡迎關(guān)注前端偵探</h3>
<input name="txt">
<button>關(guān)閉</button>
</form>
</dialog>

打開彈窗后可以直接輸入,無(wú)需額外操作,簡(jiǎn)直不要太方便

圖片

注意,注意,注意:經(jīng)測(cè)試發(fā)現(xiàn),如果添加了打開動(dòng)畫,聚焦特性就會(huì)失效

當(dāng)然,這些只是小兒科,一點(diǎn)點(diǎn)額外的 JS 也能解決,下面介紹一個(gè)系統(tǒng)級(jí)別的焦點(diǎn)隔離特性。什么意思呢?就是說(shuō)在打開彈窗后,彈窗就成了一個(gè)獨(dú)立的載體,焦點(diǎn)只能在這個(gè)范圍內(nèi)移動(dòng),也就是說(shuō),無(wú)論tab鍵如何切換,焦點(diǎn)不會(huì)跑到彈窗外面去,下面是一個(gè)對(duì)比效果

  1. 普通彈窗效果

圖片

  1. 模態(tài)彈窗效果

圖片

這個(gè)效果其實(shí)是和新出的inert屬性作用比較類似的,但是要比inert出現(xiàn)的更早,也可以說(shuō)是通過(guò)inert屬性將這種隔離特性通用化了,讓平民老百姓也可以享受這種高級(jí)特性。有興趣的可以訪問(wèn)我之前的這篇文章:快速了解 inert 屬性

五、頂層特性 top-layer

最后介紹一個(gè)即便是 JS 也無(wú)法模擬的系統(tǒng)級(jí)新特性,top-layer。

不知道大家有沒(méi)有遇到這樣的問(wèn)題,有些彈窗由于業(yè)務(wù)需要,不得已寫在了某些容器下面,即便是fixed定位,也會(huì)有失效的時(shí)候,比如下面這個(gè)例子,父容器如果有transform相關(guān)屬性并且超出隱藏,就會(huì)出現(xiàn)這樣被裁剪的情形

圖片

上面這個(gè)例子來(lái)源于 xy-ui 中的 dialog 組件[2],后續(xù)優(yōu)化,敬請(qǐng)期待~

在以前,或者說(shuō)很多框架中,都會(huì)想辦法把彈窗放到最外層的 body下,這樣就不受影響了,比如下面是vue3中的處理方式

<div>
<Teleport to="body"> <!--將子內(nèi)容傳送到body下-->
<dialog></dialog>
</Teleport>
</div>

但現(xiàn)在,有了全新的 top-layer ,一切都好辦了,比如下面是一個(gè)通過(guò)dialog.showModal()打開的彈窗

圖片

你會(huì)發(fā)現(xiàn),雖然dialog仍然在原來(lái)位置上,但真正渲染到了一個(gè)#top-layer的層級(jí)上,這個(gè)層級(jí)非常特殊,已經(jīng)超越了html文檔流,可以說(shuō)是獨(dú)一檔的存在,這樣,無(wú)論的dialog在什么位置,最后渲染的地方其實(shí)都在#top-layer層級(jí)上,自然也不會(huì)被父容器裁剪被隱藏了,示意如下

圖片

是不是和現(xiàn)代框架有些許類似呢?下面是一個(gè)彈窗里嵌套另外一個(gè)彈窗

<dialog id="dialog1">
...
<button type="button" >打開彈窗2</button>
<dialog id="dialog2">
...
</dialog>
</dialog>

效果如下

圖片

其實(shí)這也是后打開的彈窗永遠(yuǎn)要高于之前彈窗的原因,#top-layer是動(dòng)態(tài)創(chuàng)建的,只有打開的彈窗才會(huì)渲染到該層級(jí)之下。

另外,經(jīng)測(cè)試發(fā)現(xiàn),firefox 以及 safari 雖然在開發(fā)者工具上看不到#top-layer,但是dialog表現(xiàn)基本幾乎一致,應(yīng)該是已經(jīng)成為了標(biāo)準(zhǔn)規(guī)范,日后可以放心使用。

六、dom 其實(shí)也是在不斷發(fā)展的

dialog其實(shí)我在兩三年之前就有研究過(guò),那時(shí)還沒(méi)有這么多新特性,也有可能是研究不精,后來(lái)就擱置了,然后最近在項(xiàng)目中用了dialog,無(wú)意中又發(fā)現(xiàn)了很多有意思的新特性,這意味著,dom 其實(shí)也是在不斷發(fā)展的,有必要把以前已經(jīng)用過(guò)的再翻出來(lái)過(guò)一遍,說(shuō)不定還能發(fā)現(xiàn)意想不到的結(jié)果,下面是要點(diǎn)總結(jié)

  1. dialog? 的打開和關(guān)閉方法很迷惑,分別是show() / close()
  2. dialog?中表單元素在添加method=dialog屬性之后,只要觸發(fā)表單提交就會(huì)自動(dòng)關(guān)閉彈窗,無(wú)需額外 js
  3. 通過(guò)showModal()可以打開模態(tài)彈窗,并且后打開的彈窗永遠(yuǎn)比先打開的彈窗層級(jí)要高,無(wú)需手動(dòng)計(jì)算層級(jí)
  4. 打開彈窗會(huì)自動(dòng)聚焦到彈窗內(nèi)的第一個(gè)可聚焦元素,方便快速輸入
  5. 模態(tài)彈窗的焦點(diǎn)不會(huì)聚焦到彈窗外部,這和inert特性比較類似
  6. 模態(tài)彈窗其實(shí)是渲染到了html文檔流之外,一個(gè)叫#top-layer的層級(jí)上,因此不會(huì)受到原父容器的影響
責(zé)任編輯:武曉燕 來(lái)源: 前端偵探
相關(guān)推薦

2012-11-23 10:57:44

Shell

2015-08-13 09:03:14

調(diào)試技巧

2019-11-20 10:25:06

sudoLinux

2020-01-29 19:40:36

Python美好,一直在身邊Line

2021-01-05 11:22:58

Python字符串代碼

2023-02-27 09:20:24

絕對(duì)定位CSS

2014-12-08 10:39:15

2019-11-25 14:05:47

Python裝飾器數(shù)據(jù)

2021-07-12 07:59:06

安全 HTML 屬性

2021-12-17 00:10:00

ChromeDevtools功能

2018-05-10 11:50:13

Docker容器冷知識(shí)

2020-03-05 11:10:18

Left join數(shù)據(jù)庫(kù)MySQL

2010-08-06 13:15:35

2010-07-26 13:24:11

2020-05-09 08:48:21

JavaScript原生方法代碼

2010-07-21 12:37:11

Linux用戶

2010-08-10 09:13:49

Linux用戶

2011-02-14 16:11:44

2015-05-14 15:59:33

DockerLinux容器管理工具

2010-07-29 09:18:31

Linux用戶
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)