您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)JavaScript中怎么實(shí)現(xiàn)各種交互效果,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
一、了解HTML5 details, summary默認(rèn)交互行為
<details>
標(biāo)簽在Chrome,F(xiàn)irefox等瀏覽器下默認(rèn)是有展開收起行為的,例如下面HTML:
<details> <summary>這是摘要1</summary> <p>這里具體描述,標(biāo)簽相對(duì)隨意,例如這里使用的<p>標(biāo)簽。</p> </details>
結(jié)果UI表現(xiàn)為:
details標(biāo)簽?zāi)J(rèn)效果截圖
具體描述為:
只顯示了<summary>
標(biāo)簽內(nèi)容,而<p>
默認(rèn)隱藏了;
<summary>
標(biāo)簽前面出現(xiàn)了一個(gè)小三角;
小三角圖形的隱喻是:我是可點(diǎn)擊的,點(diǎn)擊我可能會(huì)出現(xiàn)寶箱。
OK,我們不妨就點(diǎn)擊一下,結(jié)果如下圖:
image.png
具體描述為:
原本隱藏的<p>
標(biāo)簽顯示出來了;
<summary>
標(biāo)簽前面的小三角方向朝下了;
此時(shí)我們?cè)僖淮吸c(diǎn)擊,<p>
標(biāo)簽內(nèi)容又會(huì)隱藏收起,箭頭方向還原,如下圖:
image.png
活脫脫一個(gè)天然的展開收起效果。
通過在<details>
標(biāo)簽上添加布爾類型的open
屬性,可以讓我們的詳情信息默認(rèn)就是展開狀態(tài),如下HTML示意:
<details open> <summary>這是摘要2</summary> <content>這里<details>標(biāo)簽設(shè)置了HTML布爾屬性open,因此,默認(rèn)是展開狀態(tài)。</content> </details>
結(jié)果如下截圖:
open屬性下的信息默認(rèn)展開
如果我們使用JS腳本手動(dòng)移除這個(gè)open
屬性,即使沒有點(diǎn)擊行為的發(fā)生,我們內(nèi)容也會(huì)收起。
<summary>
標(biāo)簽如果缺省,則<details>
元素會(huì)在內(nèi)部自動(dòng)創(chuàng)建一個(gè)<summary>
內(nèi)容,默認(rèn)的文案是“詳細(xì)信息”。如下HTML代碼:
<details open> <p>如果<summary>缺省,則會(huì)自動(dòng)補(bǔ)上,文案是“詳細(xì)信息”。</p> </details>
結(jié)果如下截圖所示:
summary 詳細(xì)信息占位示意圖
二、details瀏覽器內(nèi)置UI可以自定義
<details>標(biāo)簽?zāi)J(rèn)的小三角樣式有些簡(jiǎn)陋,在實(shí)際應(yīng)用的時(shí)候,往往不是我們希望的樣子,不要擔(dān)心,我們是可以對(duì)其進(jìn)行自定義的。在Chrome等瀏覽器下使用::-webkit-details-marker,在Firefox瀏覽器下使用::-moz-list-bullet可以對(duì)小三角進(jìn)行UI控制,例如改變顏色,改變大小,使用自定義的圖形代替,或者直接隱藏等,我們來看幾個(gè)簡(jiǎn)單的案例。
案例1:小三角右側(cè)顯示同時(shí)顏色變淡
HTML代碼如下:
<details class="details-1" open> <summary>這是示例1</summary> <content>本案例展示對(duì)小三角UI重定義:包括顯示在右側(cè),顏色減淡等。</content> </details>
CSS如下:
.details-1 summary { width: -moz-fit-content; width: fit-content; direction: rtl; } .details-1 ::-webkit-details-marker { direction: ltr; color: gray; margin-left: .5ch; } .details-1 ::-moz-list-bullet { direction: ltr; color: gray; margin-left: .5ch; }
結(jié)果如下圖所示:
三角位置和顏色示意
當(dāng)我們點(diǎn)擊摘要標(biāo)題升起的時(shí)候,表現(xiàn)為下圖(截自Firefox):
三角收起效果
而實(shí)際上實(shí)際開發(fā)的時(shí)候,對(duì)小三角UI更便捷的定制方法是:隱藏瀏覽器原生的小三角,然后借助::before或::after偽元素重新生成我們想要的UI效果,下面這個(gè)案例就將展示相關(guān)的處理。
案例2:隱藏瀏覽器原生的小三角并使用自定義三角替換
HTML結(jié)構(gòu)還是類似的:
<details class="details-2" open> <summary>這是示例2</summary> <content>本案例隱藏原生小三角,使用自定義小三角。</content> </details>
CSS主要分為2部分,一部分是隱藏瀏覽器原生的小三角,另外一部分是使用偽元素生成自定義的三角效果。
首先看一下隱藏<details>標(biāo)簽?zāi)J(rèn)的小三角的CSS:
/* 隱藏默認(rèn)三角 */ .details-2 ::-webkit-details-marker { display: none; } .details-2 ::-moz-list-bullet { font-size: 0; }
可以看到Chrome瀏覽器和Firefox瀏覽器的小三角隱藏采用的是不同的策略。在Chrome瀏覽器下,我們可以直接設(shè)置display:none進(jìn)行隱藏,但是這一招在Firefox瀏覽器下確實(shí)沒有效果的,即使設(shè)置display:none!important也是如此,根據(jù)我的測(cè)試,只有font-size:0能夠比較完美的隱藏。類似position:absolute;visibility:hidden這種常見的隱藏也是不行的,因?yàn)閜osition:absolute無法生效。
然后是自定義小三角顯示的CSS,這里采用的是::after偽元素模擬的:
/* 自定義的三角 */ .details-2 summary::after { content: ''; position: absolute; width: 1em; height: 1em; margin: .2em 0 0 .5ch; background: url(./arrow-on.svg) no-repeat; background-size: 100% 100%; transition: transform .2s; } .details-2:not([open]) summary::after { margin-top: .25em; transform: rotate(90deg); }
最終效果如下圖所示:
自定義三角效果截圖
收起時(shí)候:
收起時(shí)候效果
最后有一點(diǎn)需要注意一下,就是如果<details>
標(biāo)簽內(nèi)并沒有<summary>
元素,則我們的對(duì)三角的自定義代碼都是無效的,可以使用一個(gè)空的<summary>
元素占位,類似這樣:
<details> <summary></summary> <content>內(nèi)容。</content> </details>
UI可以定制了,但是還有個(gè)不容忽視的體驗(yàn)問題,那就是在Chrome瀏覽器下點(diǎn)擊時(shí)候會(huì)出現(xiàn)outline
輪廓,如下圖所示:
Chrome下的outline輪廓
在實(shí)際項(xiàng)目開發(fā)的時(shí)候,產(chǎn)品和設(shè)計(jì)一定會(huì)讓你把這個(gè)效果去掉的。以及,當(dāng)我們<summary>
元素點(diǎn)擊較快的時(shí)候,文本會(huì)被選中,也不是我們想看到的。
阻止文本選中,我們可以:
summary { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
對(duì)于outline輪廓,比較直接的做法是:
summary { outline: 0; }
但是這樣處理對(duì)無障礙訪問而是非常不友好的,那有沒有什么辦法兼顧視覺體驗(yàn)和無障礙訪問體驗(yàn)?zāi)兀?/p>
我的做法是這樣子的:
利用<a>標(biāo)簽的outline交互體驗(yàn)
瀏覽器對(duì)<a>標(biāo)簽元素的outline輪廓進(jìn)行了專門的體驗(yàn)優(yōu)化處理,鼠標(biāo)點(diǎn)擊的時(shí)候不顯示輪廓,鍵盤訪問時(shí)候顯示輪廓。于是我們可采用李代桃僵策略,讓<summary>元素的outline交給<a>元素,方法就是在<summary>中再內(nèi)嵌一個(gè)<a>,同時(shí)通過tabindex屬性remove掉<summary>原本的可訪問性。HTML代碼示意如下:
<details open> <summary tabindex="-1"><a href="javascript:">這是示例</a></summary> <content>點(diǎn)擊無外框,鍵盤focus有。</content> </details>
CSS如下:
summary { user-select: none; outline: 0; } summary a { color: inherit; }
此時(shí),在Chrome瀏覽器下,我們點(diǎn)擊摘要信息,沒有任何outline
輪廓出現(xiàn);但是當(dāng)我們使用Tab鍵索引時(shí)候,可以看到下圖所示的輪廓效果:
輪廓示意
輪廓區(qū)域比原生的<summary>
要小,但這無傷大雅,而且實(shí)際項(xiàng)目開發(fā)的時(shí)候,我們會(huì)去掉小箭頭,此時(shí)只要設(shè)置<a>
標(biāo)簽display:block
,則輪廓就可以和<summary>
保持一致了。
接下來,我們按下Space空格鍵,就會(huì)發(fā)現(xiàn)<details>
元素內(nèi)的內(nèi)容信息不斷的展開與收起:
收起狀態(tài)
然后上面實(shí)現(xiàn)并不完美,相比原生的<summary>元素,Enter回車鍵展開收起效果丟失了。這是因?yàn)镠TML元素中如果多個(gè)focusable同時(shí)帶click瀏覽器行為元素嵌套的時(shí)候,點(diǎn)擊里面的元素,外部元素的瀏覽器行為是不會(huì)觸發(fā)的。類似的有<label>內(nèi)嵌<a>標(biāo)簽。
對(duì)于<a>標(biāo)簽,其瀏覽器行為只能通過回車鍵觸發(fā),空格鍵是無效的;但是對(duì)于<summary>,回車鍵和空格鍵都能觸發(fā)展開收起行為,這就是為什么上面代碼空格鍵有效,回車鍵無效的原因。
如果想要同時(shí)支持回車鍵展開與收起,可以對(duì)HTML如下處理:
<details open> <summary tabindex="-1"><a href="javascript:" onClick="this.parentNode.click();">這是示例</a></summary> <content>點(diǎn)擊無外框,鍵盤focus有。</content> </details>
需要注意的是上面處理在<summary>自己額外綁定click事件時(shí)候可能會(huì)有double觸發(fā)的問題,此時(shí),阻止<a>元素的冒泡即可。
JS捕獲鍵盤行為手動(dòng)設(shè)置outline
這個(gè)方法不需要對(duì)HTML進(jìn)行任何的改動(dòng),是通過CSS和JS配合對(duì)全局的<summary>元素進(jìn)行outline優(yōu)化。
CSS如下:
summary { user-select: none; outline: 0; } summary[focus] { outline: 1px dotted; outline: 5px auto -webkit-focus-ring-color; }
JS如下:
window.addEventListener('keydown', function () { window.isKeyEvent = true; setTimeout(function () { window.isKeyEvent = false; }, 100); }); document.addEventListener('focusin', function (event) { var target = event.target; if (target && target.tagName.toLowerCase() == 'summary' && window.isKeyEvent == true) { target.setAttribute('focus', ''); } }); document.addEventListener('focusout', function (event) { var eleFocusAll = document.querySelectorAll('summary[focus]'); [].slice.call(eleFocusAll).forEach(function (summary) { summary.removeAttribute('focus'); }); });
只要把上面的CSS和JS復(fù)制到頁面中,視覺體驗(yàn)和交互體驗(yàn)完美支持的<summary>元素outline效果就有了。
表現(xiàn)為,點(diǎn)擊<summary>沒有任何outline,鍵盤focus時(shí)候出現(xiàn),且和瀏覽器原生outline效果一模一樣,Space鍵和Enter鍵展開與收起訪問完全保留。
例如下圖就是鍵盤Tab鍵focus
后回車后的效果:
鍵盤訪問回車收起后效果截圖
每每看到如此極致的用戶體驗(yàn)處理,心情都大好。
原理:
關(guān)鍵是全局監(jiān)聽keydown
事件,如果有發(fā)生,則認(rèn)為此100毫秒內(nèi)的頁面focus
行為均是鍵盤產(chǎn)生,從而有效區(qū)分是點(diǎn)擊觸發(fā)的focus
行為還是鍵盤觸發(fā)的focus
行為,如果是鍵盤觸發(fā),給<summary>
元素手動(dòng)增加outline
效果。
了解了<details>
元素的點(diǎn)擊交互行為;解決了UI定制難題;解決了outline
的體驗(yàn)問題,下面我們就可以付諸實(shí)踐,不借助任何JS來實(shí)現(xiàn)各種我們平常見到的交互效果。
實(shí)現(xiàn)最終效果如下gif:
更多展開收起gif效果
因?yàn)椤案唷痹厥窃诘撞?,因此效果?shí)現(xiàn)的要點(diǎn)的所有的內(nèi)容信息都放在<summary>
元素內(nèi)部,然后通過<details>
元素的open
屬性控制UI的變化。
HTML和CSS代碼如下,其中,最核心部分已經(jīng)紅色高亮:
<details> <summary> <p>據(jù)臺(tái)媒報(bào)道,大...青睞。</p> <div class="more"> <p>其他幾首歌曲...</p> </div> <a>更多</a> </summary> </details> ::-webkit-details-marker { display: none; } ::-moz-list-bullet { font-size: 0; float: left; } .more { display: none; } [open] .more { display: block; } [open] summary a { font-size: 0; } [open] summary a::before { content: '收起'; font-size: 14px; }
把“更多”對(duì)應(yīng)的信息放在.more元素內(nèi),然后通過[open]屬性選擇器控制器顯示,效果即達(dá)成。
效果如下gif:
下拉菜單gif效果
沒有任何JS參與。HTML結(jié)構(gòu)如下:
<details> <summary>我的消息</summary> <div class="box"> <a href>我的回答<sup>12</sup></a> <a href>我的私信</a> <a href>未評(píng)價(jià)訂單<sup>2</sup></a> <a href>我的關(guān)注</a> </div> </details>
然后CSS讓.box元素絕對(duì)定位即可,顯示和隱藏<details>元素內(nèi)置行為就搞定了。
此效果常見于條目比較多的垂直導(dǎo)航欄,新聞條目等。
例如下面實(shí)現(xiàn)的效果:
多條目菜單展開與收起效果
這個(gè)更加簡(jiǎn)單了,就是一堆<details>
元素并排放置就可以了,如下HTML:
<details open> <summary><dt>訂單中心</dt></summary> <dd><a href>我的訂單</a></dd> <dd><a href>我的活動(dòng)</a></dd> <dd><a href>評(píng)價(jià)曬單</a></dd> <dd><a href>購物助手</a></dd> </details> <details open> <summary><dt>關(guān)注中心</dt></summary> <dd><a href>關(guān)注的商品</a></dd> ... </details> <details open> ... </details>
計(jì)算CSS沒有任何設(shè)置,效果也天然達(dá)成。
案例3中的展開項(xiàng)顯示的時(shí)候是非常生硬的突然顯示,實(shí)際上我們可以借助一些選擇器技巧以及CSS3 transition
屬性讓菜單展開收起的時(shí)候是有動(dòng)畫效果的,效果如下gif截圖:
含slideup/slidedown動(dòng)畫的展開與收起
此效果實(shí)現(xiàn)原理核心是[open]
屬性選擇器,和加號(hào)+
相鄰兄弟選擇器。
首先看下HTML,展開列表結(jié)構(gòu)發(fā)生了變化,不是作為<details>
的子元素,而是作為其相鄰兄弟元素存在,HTML示意:
<details open><summary>訂單中心</summary></details> <dl> <dd><a href>我的訂單</a></dd> <dd><a href>我的活動(dòng)</a></dd> <dd><a href>評(píng)價(jià)曬單</a></dd> <dd><a href>購物助手</a></dd> </dl> ...
上面<dl>定義列表就是展開收起的內(nèi)容,其作為兄弟元素和<details>元素平起平坐,于是,我們就可以利用點(diǎn)擊<summary>元素<details>元素的open屬性會(huì)變化的特性實(shí)現(xiàn)我們想要的動(dòng)畫效果,CSS如下:
details + dl { max-height: 0; transition: max-height .25s; overflow: hidden; } [open] + dl { max-height: 100px; }
借助相鄰兄弟選擇器以及max-height任意元素slideUp/slideDown技術(shù)就可以效果達(dá)成。
這里的樹形菜單效果實(shí)現(xiàn)也很簡(jiǎn)單,多個(gè)<details>
元素相互嵌套就可以,效果Gif如下:
樹形菜單展開gif效果截圖
HTML結(jié)構(gòu)大致如下:
<details> <summary>我的視頻</summary> <details> <summary>爆肝工程師的異世界狂想曲</summary> <div>tv1-720p.mp4</div> <div>tv2-720p.mp4</div> ... <div>tv10-720p.mp4</div> </details> <details> <summary>七大罪</summary> <div>七大罪B站00合集.mp4</div> </details> <div>珍藏動(dòng)漫網(wǎng)盤地址.txt</div> <div>我們的小美好.mp4</div> </details>
CSS的主要工作就是繪制菜單前面的加號(hào)和減號(hào)圖形,例如我們可以借助background線性漸變,相關(guān)CSS如下:
details { padding-left: 20px; } summary::before { content: ''; display: inline-block; width: 12px; height: 12px; border: 1px solid #999; background: linear-gradient(to right, #999, #999) no-repeat center, linear-gradient(to top, #999, #999) no-repeat center; background-size: 2px 10px, 10px 2px; vertical-align: -2px; margin-right: 6px; margin-left: -20px; } [open] > summary::before { background: linear-gradient(to right, #999, #999) no-repeat center; background-size: 10px 2px; }
效果即達(dá)成!
五、如果只想要details/summary的語義不要行為
如果只想要<details>元素,<summary>元素的語義,但是并不需要點(diǎn)擊展開收起的行為,該怎么處理呢?
例如,某評(píng)論,或者某帖子有標(biāo)題和正文,非常符合詳情-概要-內(nèi)容的語義,但是希望是純展示的,點(diǎn)擊時(shí)候不收起,可以這么處理:
1.<summary>標(biāo)簽設(shè)置tabindex="-1"讓鍵盤無法訪問;
2.設(shè)置CSS:
summary { outline: 0; pointer-events: none; }
這樣就不能點(diǎn),也不會(huì)有outline輪廓。
兼容性如下圖:
detailas兼容性
除了IE和Edge瀏覽器,大好河山一片綠,至少移動(dòng)端可以用得比較開心。
如果想要在桌面web網(wǎng)頁使用<details>
元素的棒棒噠特性,我們可以對(duì)其進(jìn)行Polyfill
對(duì)鍵盤訪問,事件toggle都做了兼容。
如果開發(fā)策略是對(duì)不支持的IE進(jìn)行特異處理,則下面的JS判斷是否支持<details>元素的腳本可能對(duì)你有用:
var isSupportDetails = 'open' in document.createElement('details');
看完上述內(nèi)容,你們對(duì)JavaScript中怎么實(shí)現(xiàn)各種交互效果有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。