快速了解 Inert 屬性,你明白了嗎?
介紹一個全新的、和用戶行為息息相關的屬性:inert。
HTMLElement.inert - Web APIs | MDN (mozilla.org)[1]。
有了這個屬性,可以更加輕易地控制很多交互行為,花幾分鐘了解一下吧!
一、inert 是什么?
inert是 HTMLElement 的一個布爾屬性,意為"惰性",簡單來說,可以禁用一切交互,包括鼠標點擊、選中、拖拽、鍵盤操作等等,舉個例子:
<div inert>
<p>`inert`是 HTMLElement 的一個布爾屬性,意為"惰性",簡單來說,可以禁用一切交互</p>
<a href="/link">link</a>
<button>button1</button>
<button>button2</button>
</div>
下面是實際效果:
可以看到,添加了inert屬性后,整個元素無法進行任何交互,就好像整個 DOM 都被凍結(jié)了一樣,所以理解成“凍結(jié)”,可能會更好一些
你也可以查看線上demo:html inert (codepen.io)[2]或者html inert (runjs.work)[3]。
另外,inert是一個布爾類型的屬性,就是和平時見到的disabled、hidden等一致,只要有這個屬性,就表示為true,不存在才是false。
<!--以下都為true-->
<div inert>...</div>
<div inert="true">...</div>
<div inert="false">...</div>
<!--以下才是false-->
<div>...</div>
這個需要注意一下:
二、inert 的實際應用
一個新的屬性,總會聯(lián)想到一些實際應用場景,下面介紹兩個案例:
1. a鏈接的禁用
在過去,要禁用一個a鏈接可能會這樣:
a{
pointer-events: none;
}
但是,這樣只是阻止了鼠標點擊行為,鍵盤還是可以focus到的,為了阻止鍵盤事件,還需要添加tabindex=-1。
<a tabindex="-1" href="/xxx"></a>
這樣鍵盤就不會聚焦到a鏈接上了。
除此之外,還有一種更為暴力的方案,直接去除a的href屬性。
a.href = ''
這樣去除之后,a就僅僅是一個普通的標簽了,也不會被聚焦到了。不過這個方案需要在某處保留a原有的href屬性,以便后續(xù)還原。
如果用inert屬性,直接就可以實現(xiàn)全方位的禁用了。
<a inert href="/xxx"></a>
還可以通過[inert]屬性自定義樣式。
a[inert]{
opacity: .5
}
這樣在視覺上可以更好地區(qū)分哪些部分是禁用的。
當然,不僅僅是a鏈接,其他任何元素都可以用這種方式來禁用。
2. 彈窗中的焦點
很多彈窗內(nèi)部也會有交互,比較常見的確認、取消按鈕。
如果需要兼顧到鍵盤訪問,肯定是希望在彈窗打開后,焦點只能在彈窗內(nèi)部切換,而不能移動到外部,比如像這樣,焦點仍然可以跑到外面去。
現(xiàn)在有了inert,就可以很方便的處理這個問題了,只需要在外面的元素上添加inert。
<div inert>
<button id="btn">打開彈窗</button>
<a href="/link">link</a>
</div>
<dialog>
...
</dialog>
效果如下:
其實,如果是用原生的彈窗,通過showModal打開后,已經(jīng)天然支持局部焦點特性了。
dialog.showModal()
這樣可以省去大量的焦點控制控制,還有什么理由不去使用原生呢?
三、兼容性和總結(jié)
這類比較偏體驗的屬性其實是不太需要關注兼容的,大部分地方其實都用不上,如果你悄悄在某個地方用了也無妨,瀏覽器能支持更好,不支持也不影響主要功能。下面是兼容性情況:
全兼容!除了版本要求有點高以外。
沒關系,還有polyfill可以用,如下:
WICG/inert: Polyfill for the inert attribute and property. (github.com)[4]
看了一下大致原理,和以前的處理基本一致,pinter-events和tabindex=-1的結(jié)合,阻止鼠標和鍵盤行為。
總之即使非常新,也可以提前使用起來了,下面總結(jié)一下主要知識點:
- inert是一個 HTMLElement 屬性,可以禁用一切用戶交互,非常徹底,就像“凍結(jié)”了一樣。
- inert?是一個布爾屬性,只要存在該屬性就是true,否則為false。
- inert?可以很方便的禁用a鏈接,也包括其他任意元素。
- inert可以很方便的控制焦點的作用范圍,讓彈窗內(nèi)的焦點不會跳到外部。
- 原生dialog.showModal已經(jīng)天然具備局部焦點的特性,大家可以多多使用。
參考資料
[1] HTMLElement.inert - Web APIs | MDN (mozilla.org): https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert
[2] html inert (codepen.io): https://codepen.io/xboxyan/pen/oNdQBNp
[3] html inert (runjs.work): https://runjs.work/projects/39d0efb5b0a442ed
[4] WICG/inert: Polyfill for the inert attribute and property. (github.com): https://github.com/WICG/inert