[極致用戶體驗(yàn)] 你的 Link Button 能讓用戶選擇新頁(yè)面打開(kāi)嗎?
點(diǎn)擊上方?前端陽(yáng)光,關(guān)注公眾號(hào)
回復(fù)加群,加入技術(shù)交流群交流群
作者是公眾號(hào)「線下聚會(huì)游戲」HullQin,開(kāi)發(fā)了一些聯(lián)機(jī)桌游網(wǎng)頁(yè)(UNO、斗地主、五子棋等),總結(jié)了一些前端經(jīng)驗(yàn),分享給大家。
1. 什么是Link Button?
我想表達(dá)的是「需要導(dǎo)航能力的可點(diǎn)擊元素」(Link Button是為了方便溝通而創(chuàng)造的名詞)
我用Link表示導(dǎo)航能力,用Button表示可點(diǎn)擊元素。
什么是導(dǎo)航能力?
切換路由(URL)的能力。
標(biāo)簽因?yàn)?code style="margin: 3px;padding: 3px;font-size: 14px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;border-radius: 4px;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);word-break: break-all;">href屬性,天然具備導(dǎo)航能力。而標(biāo)簽沒(méi)href,只能在onclick事件中,用JS控制打開(kāi)新頁(yè)面。
2. 用戶怎么選擇新頁(yè)面打開(kāi)?
分2種情況,你可以在掘金頁(yè)面試一下:
2.1 新標(biāo)簽頁(yè)(tab)打開(kāi)
Command(Mac)/Ctrl(Windows) + 鼠標(biāo)左鍵click鼠標(biāo)中鍵click 鼠標(biāo)右鍵click,在菜單選擇“在新標(biāo)簽頁(yè)中打開(kāi)鏈接” (無(wú)障礙)通過(guò) Tab,選中鏈接時(shí),按Command(Mac)/Ctrl(Windows) + 回車鍵Enter
2.2 新窗口(window)打開(kāi)
Shift?+ 鼠標(biāo)左鍵click鼠標(biāo)右鍵click,在菜單選擇“在窗口中打開(kāi)鏈接” (無(wú)障礙)通過(guò) Tab,選中鏈接時(shí),按Shift?+ 回車鍵Enter
3. 什么是極致的用戶體驗(yàn)?
一切導(dǎo)航功能,都應(yīng)該給用戶完整的『新窗口』打開(kāi)能力。
只要你的按鈕會(huì)導(dǎo)致頁(yè)面切換,就應(yīng)該允許用戶用1.2提到的任意方式,在新頁(yè)面打開(kāi)。
4. 如何優(yōu)雅的實(shí)現(xiàn)“Link Button”
4.1 新手方案:+onclick
我剛學(xué)前端時(shí),常常喜歡用實(shí)現(xiàn)導(dǎo)航功能,只要在onclick里寫window.open(url)或window.document.href = url或window.location.replace(URL)就好了。
缺點(diǎn)很明顯
用戶根本無(wú)法選擇在新頁(yè)面or本頁(yè)面打開(kāi),只能接受你的實(shí)現(xiàn)。 用戶根本不知道點(diǎn)擊按鈕后會(huì)發(fā)生什么。(如果是 標(biāo)簽,用戶hover時(shí),會(huì)在瀏覽器左下方看到新頁(yè)面 URL)
4.2 中手方案:+onclick+event
工作2個(gè)月后,我懂了點(diǎn)用戶體驗(yàn),但知識(shí)局限于:用戶點(diǎn)擊Command(Mac)/Ctrl(Windows) + 鼠標(biāo)左鍵click,可以新標(biāo)簽頁(yè)打開(kāi)。所以我這么寫:
//?buttonElement?是html中某個(gè)
buttonElement.onclick?=?function?(event)?{
??if?(event.ctrlKey?||?event.metaKey)?{
????window.open('某個(gè)url');
??}?else?{
????window.document.href?=?'某個(gè)url';
??}
};
復(fù)制代碼
觸發(fā)onclick時(shí),通過(guò)event參數(shù)判斷下有沒(méi)有按下Ctrl或Command:如果有按下,就新標(biāo)簽頁(yè)打開(kāi);否則本頁(yè)面跳轉(zhuǎn)。
其實(shí)這種方案只比新手方案好一點(diǎn)點(diǎn),問(wèn)題沒(méi)有得到根本解。
4.3 高手方案:+onclick+event
工作半年后,同事告訴我中鍵click也能新標(biāo)簽頁(yè)打開(kāi)。我又學(xué)了點(diǎn)html無(wú)障礙規(guī)范,才明白一個(gè)道理:
導(dǎo)航能力,就交給專業(yè)的標(biāo)簽做,兼容性最好,能力最全面。
除了天然支持新頁(yè)面打開(kāi),還有些好處:鼠標(biāo)Hover上去時(shí),瀏覽器會(huì)提示新頁(yè)面地址,并且也能直接右鍵復(fù)制地址,便于分享!
但是!有2個(gè)問(wèn)題需要解決:
4.3.1 樣式問(wèn)題
和樣式是有差異的。產(chǎn)品形態(tài)上希望用按鈕,我們就不能用超鏈接樣式。
該問(wèn)題很好解,把你按鈕樣式復(fù)制一份,或者把相關(guān)class放到標(biāo)簽上,就基本一樣了,如果還有樣式差異,就再覆蓋一下的默認(rèn)樣式(大多數(shù)瀏覽器會(huì)給它設(shè)置字體顏色、下劃線這2個(gè)默認(rèn)樣式):
a,?a:link,?a:visited,?a:hover,?a:active?{
??color:?inherit;
??text-decoration:?none;
}
復(fù)制代碼
4.3.2 JS邏輯問(wèn)題
如果導(dǎo)航,需要其它JS邏輯,就無(wú)法只用和href實(shí)現(xiàn),并且這種情況還不少。例如:
跳轉(zhuǎn)時(shí),需要傳路由state。 某些邏輯,只希望本頁(yè)面跳轉(zhuǎn)時(shí)執(zhí)行,不允許新頁(yè)面打開(kāi)時(shí)執(zhí)行(因?yàn)镴S只能執(zhí)行本頁(yè)面的JS,如果在新頁(yè)面打開(kāi),本頁(yè)面應(yīng)該保持不變,不能執(zhí)行那段JS,例如React Router中的 )。某個(gè)按鈕,直接點(diǎn)擊時(shí)是 window.history.back(),但也允許新窗口打開(kāi)上個(gè)頁(yè)面地址(這個(gè)問(wèn)題更加復(fù)雜,請(qǐng)期待我的下篇文章,會(huì)做詳細(xì)講解)
現(xiàn)在我想告訴你:這些問(wèn)題,也是有解的!
這些問(wèn)題的解決方案
還記得我曾經(jīng)是個(gè)“中手”嗎?我的“中手方案”剛好可以解決這個(gè)難題!把中手方案邏輯改改,就可以了:
//?aElement是html中的某個(gè)包含href的元素:?某個(gè)鏈接
aElement.onclick?=?function?(event)?{
??if?(event.button?!==?0)?return;
??if?(event.ctrlKey?||?event.metaKey?||?event.shiftKey?||?event.altKey)?return;
??event.preventDefault();
??//?如果用戶期望本頁(yè)面跳轉(zhuǎn)(而非新窗口打開(kāi)),則執(zhí)行以下邏輯
??window.history.pushState({?pageState:?123?},?'',?'new-page.html');
};
復(fù)制代碼
解釋下:
event.button
表示按下的是鼠標(biāo)哪個(gè)按鍵:
0:主按鍵,通常指鼠標(biāo)左鍵或默認(rèn)值 1:輔助按鍵,通常指鼠標(biāo)滾輪中鍵 2:次按鍵,通常指鼠標(biāo)右鍵 3:第四個(gè)按鈕,通常指瀏覽器后退按鈕 4:第五個(gè)按鈕,通常指瀏覽器的前進(jìn)按鈕
這里我們只管理左鍵就好,其它按鍵都保持瀏覽器默認(rèn)行為(所以非0直接return,不執(zhí)行JS邏輯,執(zhí)行原生行為)。
event.xxxKey
event.ctrlKey: MAC上表示Control鍵,Windows上表示Ctrl鍵。event.metaKey: MAC上表示Command鍵,Windows上表示W(wǎng)indows鍵。event.shiftKey: Shift鍵。event.altKey: MAC上表示Option鍵,Windows上表示Alt鍵。
按照規(guī)范,這些鍵按下時(shí),不應(yīng)該在本頁(yè)面繼續(xù)跳轉(zhuǎn),而是會(huì)發(fā)生這些事:
ctrlKey?+?click: Mac上表示右鍵點(diǎn)擊該元素,Windows上表示新標(biāo)簽頁(yè)打開(kāi)頁(yè)面。metaKey?+?click: Mac上表示新標(biāo)簽頁(yè)打開(kāi)頁(yè)面,Windows上打開(kāi)Windows開(kāi)始菜單。shiftKey?+?click: 新窗口打開(kāi)頁(yè)面。altKey?+?click: 下載頁(yè)面。
event.preventDefault()
如果用戶只是普通的左鍵點(diǎn)擊了鏈接,沒(méi)按任何xxxKey,就應(yīng)該阻止標(biāo)簽?zāi)J(rèn)行為,由我們的JS去接管,自由操控跳轉(zhuǎn)。
但如果用戶按了任何xxxKey,或是點(diǎn)了鼠標(biāo)其它鍵,都應(yīng)該讓瀏覽器接管后續(xù)邏輯。
Oh!真是完美的方案!
5. 寫在最后
如果你像我一樣,喜歡代碼純粹一點(diǎn),不夾雜冗余功能,就可以自己寫Link Button,封裝自己所需的組件 ??
如果你只是為了完成別人的需求,還是直接用組件庫(kù)吧 ??
但是,即使你用組件庫(kù),里面有Menu、Button組件,你一定要想清楚,如果需要頁(yè)面跳轉(zhuǎn),務(wù)必找找Link組件,盡量使用Link來(lái)表達(dá)導(dǎo)航。
關(guān)于導(dǎo)航的用戶體驗(yàn),非常細(xì)節(jié),太重要了!一個(gè)網(wǎng)頁(yè)的質(zhì)量,一個(gè)前端開(kāi)發(fā)者的水平,能直接從導(dǎo)航欄細(xì)節(jié)中看出。
最后希望大家都能開(kāi)發(fā)出用戶體驗(yàn)完美的“Link Button”!
關(guān)于本文
作者:公眾號(hào)「線下聚會(huì)游戲」HullQin
https://juejin.cn/post/7089483164908781604

往期推薦
我組建了技術(shù)交流群,里面有很多?大佬,歡迎進(jìn)來(lái)交流、學(xué)習(xí)、共建。回復(fù)?加群?即可。后臺(tái)回復(fù)「電子書」即可免費(fèi)獲取?27本?精選的前端電子書!回復(fù)內(nèi)推,可內(nèi)推各廠內(nèi)推碼
???“分享、點(diǎn)贊、在看” 支持一波??

