1. 程式人生 > >前端優秀實踐不完全指南

前端優秀實踐不完全指南

本文其實應該叫,Web 使用者體驗設計提升指南。 一個 Web 頁面,一個 APP,想讓別人用的爽,也就是所謂的良好的使用者體驗,我覺得他可能包括但不限於: + 急速的開啟速度 + 眼前一亮的 UI 設計 + 酷炫的動畫效果 + 豐富的個性化設定 + 便捷的操作 + 貼心的細節 + 關注殘障人士,良好的可訪問性 + ... 所謂的使用者體驗設計,其實是一個比較虛的概念,是秉承著**以使用者為中心的思想**的一種設計手段,以使用者需求為目標而進行的設計。設計過程注重以使用者為中心,使用者體驗的概念從開發的最早期就開始進入整個流程,並貫穿始終。 良好的使用者體驗設計,是產品每一個環節共同努力的結果。 除去一些很難一蹴而就的,本文將就**頁面展示**、**互動細節**、**可訪問性**三個方面入手,羅列一些在實際的開發過程中,積攢的一些有益的經驗。通過本文,你將能收穫到: 1. 瞭解到一些小細節是如何影響使用者體驗的 2. 瞭解到如何在儘量小的開發改動下,提升頁面的使用者體驗 3. 瞭解到一些優秀的互動設計細節 4. 瞭解基本的無障礙功能及頁面可訪問性的含義 5. 瞭解基本的提升頁面可訪問性的方法 ## 頁面展示 就整個頁面的展示,頁面內容的呈現而言,有一些小細節是需要我們注意的。 ### 整體佈局 先來看看一些佈局相關的問題。 對於大部分 PC 端的專案,我們首先需要考慮的肯定是最外層的一層包裹。假設就是 `.g-app-wrapper`。 ```HTML ``` 首先,對於 `.g-app-wrapper`,有幾點,是我們在專案開發前必須弄清楚的: 1. 專案是全屏佈局還是定寬佈局? 2. 對於全屏佈局,需要適配的最小的寬度是多少? 對於定寬佈局,就比較方便了,假設定寬為 `1200px`,那麼: ```CSS .g-app-wrapper { width: 1200px; margin: 0 auto; } ``` 利用 `margin: 0 auto` 實現佈局的水平居中。在螢幕寬度大於 `1200px` 時,兩側留白,當然螢幕寬度小於 `1200px` 時,則出現滾動條,保證內部內容不亂。 ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3ca2418b6ef046d7b2635a2e10a4610c~tplv-k3u1fbpfcp-watermark.image) 對於現代佈局,更多的是全屏佈局。其實現在也更提倡這種佈局,即使用可隨使用者裝置的尺寸和能力而變化的自適應佈局。 通常而言是左右兩欄,左側定寬,右側自適應剩餘寬度,當然,會有一個最小的寬度。那麼,它的佈局應該是這樣: ```HTML ``` ```CSS .g-app-wrapper { display: flex; min-width: 1200px; } .g-sidebar { flex-basis: 250px; margin-right: 10px; } .g-main { flex-grow: 1; } ``` ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/865f09c168c04c808104b8540277a6f7~tplv-k3u1fbpfcp-watermark.image) 利用了 flex 佈局下的 `flex-grow: 1`,讓 `.main` 進行伸縮,佔滿剩餘空間,利用 `min-width` 保證了整個容器的最小寬度。 當然,這是最基本的自適應佈局。對於現代佈局,我們應該儘可能的考慮更多的場景。做到: ![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4a1120cd519248cb8f706c63d28176be~tplv-k3u1fbpfcp-watermark.image) ### 底部 footer 下面一種情形也是非常常見的一個情景。 頁面存在一個 footer 頁尾部分,如果整個頁面的內容高度小於視窗的高度,則 footer 固定在視窗底部,如果整個頁面的內容高度大於視窗的高度,則 footer 正常流排布(也就是需要滾動到底部才能看到 footer)。 看看效果: ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4fe995f026044f63af807b601378294f~tplv-k3u1fbpfcp-watermark.image) 嗯,這個需求如果能夠使用 flex 的話,使用 `justify-content: space-between` 可以很好的解決,同理使用 `margin-top: auto` 也非常容易完成: ```HTML ... ``` ```CSS .g-container { height: 100vh; display: flex; flex-direction: column; } .g-footer { margin-top: auto; flex-shrink: 0; height: 30px; background: deeppink; } ``` [Codepen Demo -- sticky footer by flex margin auto](https://codepen.io/Chokcoco/pen/pmrbWX) > 當然,實現它的方法有很多,這裡僅給出一種推薦的解法。 ### 處理動態內容 - 文字超長 對於所有接收後端介面欄位的文字展示類的介面。都需要考慮全面(防禦性程式設計:所有的外部資料都是不可信的),正常情況如下,是沒有問題的。 ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d465e773d8d84906ab73cd92d7e1e522~tplv-k3u1fbpfcp-zoom-1.image) 但是我們是否考慮到了文字會超長?超長了會折行還是換行? ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb60f1b3201140dfbe209ce6314ddb21~tplv-k3u1fbpfcp-zoom-1.image) 對於**單行文字**,使用單行省略: ```CSS { width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } ``` ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bb95d86d3c664799a70f27de9b73f725~tplv-k3u1fbpfcp-zoom-1.image) 當然,目前對於**多行文字**的超長省略,相容性也已經非常好了: ```CSS { width: 200px; overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } ``` ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c5697f5f04440af94a2a584d7259eec~tplv-k3u1fbpfcp-zoom-1.image) ### 處理動態內容 - 保護邊界 對於一些動態內容,我們經常使用 `min/max-width` 或 `min/max-height` 對容器的高寬限度進行合理的控制。 在使用它們的時候,也有一些細節需要考慮到。 譬如經常會使用 `min-width` 控制按鈕的最小寬度: ```CSS .btn { ... min-width: 120px; } ``` ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/105a4921dba74801943595494321ba58~tplv-k3u1fbpfcp-zoom-1.image) 當內容比較少的時候是沒問題的,但是當內容比較長,就容易出現問題。使用了 `min-width` 卻沒考慮到按鈕的過長的情況: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ebec14ad3ed144a89faa33a456349f74~tplv-k3u1fbpfcp-zoom-1.image) 這裡就需要配合 padding 一起: ```CSS .btn { ... min-width: 88px; padding: 0 16px } ``` 借用[Min and Max Width/Height in CSS](https://ishadeed.com/article/min-max-css/)中一張非常好的圖,作為釋義: ![min-width-2](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4bb7075934fe41fcaf08145a00ff7e34~tplv-k3u1fbpfcp-zoom-1.image) ### 0 內容展示 這個也是一個常常被忽略的地方。 頁面經常會有列表搜尋,列表展示。那麼,既然存在有資料的正常情況,當然也會存在搜尋不到結果或者列表無內容可展示的情形。 對於這種情況,一定要注意 0 結果頁面的設計,同時也要知道,這也是引導使用者的好地方。對於 0 結果頁面,分清楚: + **資料為空**:其中又可能包括了使用者無許可權、搜尋無結果、篩選無結果、頁面無資料 + **異常狀態**:其中又可能包括了網路異常、伺服器異常、載入失敗等待 不同的情況可能對應不同的 0 結果頁面,附帶不同的操作引導。 譬如網路異常: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/110c59469b8d460fbbf5fc4f3d512c78~tplv-k3u1fbpfcp-zoom-1.image) 或者確實是 0 結果: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0985420f58b643ed9450deef3c7b6b87~tplv-k3u1fbpfcp-zoom-1.image) 關於 0 結果頁面設計,可以詳細看看這篇文章:[如何設計產品的空白頁面?](http://www.woshipm.com/pd/3742114.html) 小小總結一下,上述比較長的篇幅一直都在闡述一個道理,**開發時,不能僅僅關注正常現象,要多考慮各種異常情況,思考全面。做好各種可能情況的處理**。 ### 圖片相關 圖片在我們的業務中應該是非常的常見了。有一些小細節是需要注意的。 #### 給圖片同時設定高寬 有的時候和產品、設計會商定,只能使用固定尺寸大小的圖片,我們的佈局可能是這樣: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f963c109bf47406bb21b9a8e4e70e1af~tplv-k3u1fbpfcp-zoom-1.image) 對應的佈局: ```HTML
  • 圖片描述

``` ```CSS ul li img { width: 150px; } ``` 當然,萬一假設後端接口出現一張非正常大小的圖片,上述不加保護的佈局就會出問題: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f98f68f898e545fdb3345f40fda67407~tplv-k3u1fbpfcp-zoom-1.image) 所以對於圖片,我們總是建議同時寫上高和寬,避免因為圖片尺寸錯誤帶來的佈局問題: ```CSS ul li img { width: 150px; height: 100px; } ``` 同時,給 `` 標籤同時寫上高寬,可以在圖片未載入之前提前佔住位置,避免圖片從未載入狀態到渲染完成狀態高寬變化引起的重排問題。 #### `object-fit` 當然,限制高寬也會出現問題,譬如圖片被拉伸了,非常的難看: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b477962b361c491a8e6e47bd054e2c95~tplv-k3u1fbpfcp-zoom-1.image) 這個時候,我們可以藉助 `object-fit`,它能夠指定可替換元素的內容(也就是圖片)該如何適應它的父容器的高寬。 ```CSS ul li img { width: 150px; height: 100px; object-fit: cover; } ``` 利用 `object-fit: cover`,使圖片內容在保持其寬高比的同時填充元素的整個內容框。 ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6b7060a6c62641c8ba4ab60950283f0b~tplv-k3u1fbpfcp-zoom-1.image) `object-fit` 還有一個配套屬性 `object-position`,它可以控制圖片在其內容框中的位置。(類似於 `background-position`),m預設是 `object-position: 50% 50%`,如果你不希望圖片居中展示,可以使用它去改變圖片實際展示的 position 。 ```CSS ul li img { width: 150px; height: 100px; object-fit: cover; object-position: 50% 100%; } ``` ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/16cadfa094c14755a9fc7773be672647~tplv-k3u1fbpfcp-zoom-1.image) 像是這樣,`object-position: 100% 50%` 指明從底部開始展示圖片。這裡有一個很好的 Demo 可以幫助你理解 `object-position`。 [CodePen Demo -- Object position](https://codepen.io/robinrendle/pen/raGOOJ) #### 考慮螢幕 dpr -- 響應式圖片 正常情況下,圖片的展示應該沒有什麼問題了。但是對於有圖片可展示的情況下,我們還可以做的更好。 在移動端或者一些高清的 PC 螢幕(蘋果的 MAC Book),螢幕的 dpr 可能大於 1。這種時候,我們可能還需要考慮利用多倍圖去適配不同 dpr 的螢幕。 正好,`` 標籤是有提供相應的屬性 `srcset` 讓我們進行操作的。 ```HTML ``` 當然,這是比較舊的寫法,`srcset` 新增了新的 w 寬度描述符,所以更好的寫法是: ```HTML ``` 利用 `srcset`,我們可以給不同 dpr 的螢幕,提供最適合的圖片。 > 上述出現了一些概念,dpr,srcset 屬性,不太瞭解的可以移步 [前端基礎知識概述](https://github.com/chokcoco/cnblogsArticle/issues/25) #### 圖片丟失 好了,當圖片連結沒問題時,已經處理好了。接下來還需要考慮,當圖片連結掛了,應該如何處理。 處理的方式有很多種。最好的處理方式,是我最近在張鑫旭老師的這篇文章中 -- [圖片載入失敗後CSS樣式處理最佳實踐](https://www.zhangxinxu.com/wordpress/2020/10/css-style-image-load-fail/) 看到的。這裡簡單講下: 1. 利用圖片載入失敗,觸發 `` 元素的 `onerror` 事件,給載入失敗的 `` 元素新增一個樣式類 2. 利用新增的樣式類,配合 `` 元素的偽元素,展示預設兜底圖的同時,還能一起展示 `` 元素的 `alt` 資訊 ```HTML ``` ```CSS img.error { position: relative; display: inline-block; } img.error::before { content: ""; /** 定位程式碼 **/ background: url(error-default.png); } img.error::after { content: attr(alt); /** 定位程式碼 **/ } ``` 我們利用偽元素 `before` ,載入預設錯誤兜底圖,利用偽元素 `after`,展示圖片的 `alt` 資訊: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db77417d46564081b2118bae78a09956~tplv-k3u1fbpfcp-zoom-1.image) OK,到此,完整的對圖片的處理就算完成了,完整的 Demo 你可以戳這裡看看: [CodePen Demo -- 圖片處理](https://codepen.io/Chokcoco/pen/WNGgNqv?editors=1100) ## 互動設計優化 接下來一個大環節是關於一些互動的細節。對於互動設計,一些比較通用的準則: + Don’t make me think + 符合使用者的習慣與預期 + 操作便利 + 做適當的提醒 + 不強迫使用者 ### 過渡與動畫 在我們的互動過程中,**適當的增加過渡與動畫,能夠很好的讓使用者感知到頁面的變化**。 譬如我們頁面上隨處可見 loading 效果,其實就是這樣一種作用,讓使用者感知頁面正在載入,或者正在處理某些事務。 ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5a0aed7c7e1541e4938dc15364941b17~tplv-k3u1fbpfcp-watermark.image) ### 滾動優化 滾動也是操作網頁中非常重要的一環。看看有哪些可以優化的點: #### 滾動平滑:使用 `scroll-behavior: smooth` 讓滾動絲滑 使用 `scroll-behavior: smooth`,可以讓滾動框實現平穩的滾動,而不是突兀的跳動。看看效果,假設如下結構: ```HTML
First section
Second section
Third section
``` 不使用 `scroll-behavior: smooth`,是突兀的跳動切換: ![scrol](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ece4fb09a046457f9b59ec8dc9e82f86~tplv-k3u1fbpfcp-zoom-1.image) 給可滾動容器新增 `scroll-behavior: smooth`,實現平滑滾動: ```CSS { scroll-behavior: smooth; } ``` ![scroll2](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/efcabe865fa44d07b89d48b6ba4d4c40~tplv-k3u1fbpfcp-zoom-1.image) #### 使用 `scroll-snap-type` 優化滾動效果 `sroll-snap-type` 可能算得上是新的滾動規範裡面最核心的一個屬性樣式。 **[scroll-snap-type](https://developer.mozilla.org/zh-CN/docs/Web/CSS/scroll-snap-type)**:屬性定義在滾動容器中的一個臨時點(snap point)如何被嚴格的執行。 光看定義有點難理解,簡單而言,這個屬性規定了一個容器是否對內部滾動動作進行捕捉,並且規定了如何去處理滾動結束狀態。讓滾動操作結束後,元素停止在適合的位置。 看個簡單示例: ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fdc2b27afaef4b5782842a74cbe7cdef~tplv-k3u1fbpfcp-zoom-1.image) 當然,`scroll-snap-type` 用法非常多,可控制優化的點很多,限於篇幅無法一一展開,具體更詳細的用法可以看看我的另外一篇文章 -- [使用 sroll-snap-type 優化滾動](https://github.com/chokcoco/iCSS/issues/74) #### 控制滾動層級,避免頁面大量重排 這個優化可能稍微有一點難理解。需要了解 CSS 渲染優化的相關知識。 先說結論,控制滾動層級的意思是**儘量讓需要進行 CSS 動畫(可以是元素的動畫,也可以是容器的滾動)的元素的 z-index 保持在頁面最上方,避免瀏覽器建立不必要的圖形層(GraphicsLayer),能夠很好的提升渲染效能**。 這一點怎麼理解呢,一個元素觸發建立一個 Graphics Layer 層的其中一個因素是: + 元素有一個 z-index 較低且包含一個複合層的兄弟元素 根據上述這點,我們對滾動效能進行優化的時候,需要注意兩點: 1. 通過生成獨立的 GraphicsLayer,利用 GPU 加速,提升滾動的效能 2. 如果本身滾動沒有效能問題,不需要獨立的 GraphicsLayer,也要注意滾動容器的層級,避免因為層級過高而被其他建立了 GraphicsLayer 的元素合併,被動的生成一個 Graphics Layer ,影響頁面整體的渲染效能 如果你對這點還有點懵,可以看看這篇文章 -- [你所不知道的 CSS 動畫技巧與細節](https://github.com/chokcoco/iCSS/issues/27) ### 點選互動優化 在使用者點選互動方面,也有一些有意思的小細節。 #### 優化手勢 -- 不同場景應用不同 `cursor` 對於不同的內容,最好給與不同的 `cursor` 樣式,CSS 原生提供非常多種常用的手勢。 在不同的場景使用不同的滑鼠手勢,**符合使用者的習慣與預期**,可以很好的提升使用者的互動體驗。 首先對於按鈕,就至少會有 3 種不同的 cursor,分別是可點選,不可點選,等待中: ```CSS { cursor: pointer; // 可點選 cursor: not-allowed; // 不可點選 cursor: wait; // loading } ``` ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a92c0971be934ba9a7555b973ac27a5b~tplv-k3u1fbpfcp-zoom-1.image) 除此之外,還有一些常見的,對於一些可輸入的 Input 框,使用 `cursor: text`,對於提示 Tips 類使用 `cursor: help`,放大縮小圖片 `zoom-in`、`zoom-out` 等等: ![image](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4b0c2e854e243d9bd07c7d82b71d57f~tplv-k3u1fbpfcp-zoom-1.image) 一些常用的簡單列一列: + 按鈕可點選: `cursor: pointer` + 按鈕禁止點選:`cursor: not-allowed` + 等待 Loading 狀態:`cursor: wait` + 輸入框:cursor: text; + 圖片檢視器可放大可縮小:`cursor: zoom-in/ zoom-out` + 提示:cursor: help; 當然,實際 `cursor` 還支援非常多種,可以在 [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor) 或者下面這個 CodePen Demo 中檢視這裡看完整的列表: [CodePen Demo -- Cursor Demo](https://codepen.io/Chokcoco/pen/poEBLqr) ### 點選區域優化 -- 偽元素擴大點選區域 按鈕是我們網頁設計中十分重要的一環,而按鈕的設計也與使用者體驗息息相關。 考慮這樣一個場景,在搖晃的車廂上或者是單手操作著螢幕,有的時候一個按鈕,死活也點不到。 讓使用者更容易的點選到按鈕無疑能很好的增加使用者體驗及可提升頁面的訪問性,尤其是在移動端,按鈕通常都很小,但是受限於設計稿或者整體 UI 風格,我們不能直接去改變按鈕元素的高寬。 那麼這個時候有什麼辦法在不改變按鈕原本大小的情況下去增加他的點選熱區呢? 這裡,偽元素也是可以代表其宿主元素來響應的滑鼠互動事件的。藉助偽元素可以輕鬆幫我們實現,我們可以這樣寫: ```CSS .btn::befoer{ content:""; position:absolute; top:-10px; right:-10px; bottom:-10px; left:-10px; } ``` 當然,在 PC 端下這樣子看起來有點奇怪,但是合理的用在點選區域較小的移動端則能取到十分好的效果,效果如下: ![608782-20160527112625428-906375003](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/499f2bb64ead4a1fb36639b66fe98649~tplv-k3u1fbpfcp-zoom-1.image) 在按鈕的偽元素沒有其它用途的時候,這個方法確實是個很好的提升使用者體驗的點。 ### 快速選擇優化 -- `user-select: all` 作業系統或者瀏覽器通常會提供一些快速選取文字的功能,看看下面的示意圖: ![layout3](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/79cb00558fe14e50bafb20b2b4b47e9e~tplv-k3u1fbpfcp-zoom-1.image) 快速單擊兩次,可以選中單個單詞,快速單擊三次,可以選中一整行內容。但是如果有的時候我們的核心內容,被分隔符分割,或者潛藏在一整行中的一部分,這個時候選取起來就比較麻煩。 利用 `user-select: all`,可以將需要一次選中的內容進行包裹,使用者只需要點選一次,就可以選中該段資訊: ```CSS .g-select-all { user-select: all } ``` 給需要一次選中的資訊,加上這個樣式後的效果,這個細節作用在一些需要複製貼上的場景,非常好用: ![layout4](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a18f99c8e4064164815ecc5c6e774994~tplv-k3u1fbpfcp-zoom-1.image) [CodePen -- user-select: all 示例](https://codepen.io/Chokcoco/pen/LYRBmEJ) ### 選中樣式優化 -- `::selection` 當然,如果你想更進一步,CSS 還有提供一個 `::selection` 偽類,可以控制選中的文字的樣式(只能控制`color`, `background`, `text-shadow`),進一步加深效果。 ![layout5](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cbbfee432f0042c794109cea39403faf~tplv-k3u1fbpfcp-zoom-1.image) [CodePen -- user-select: all && ::selection 控制選中樣式](https://codepen.io/Chokcoco/pen/RwGYWNj) ### 新增禁止選擇 -- `user-select: none` 有快速選擇,也就會有它的對立面 -- 禁止選擇。 對於一些可能頻繁操作的按鈕,可能出現如下尷尬的場景: + 文字按鈕的快速點選,觸發了瀏覽器的雙擊快速選擇,導致文字被選中: ![btn-click](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dac6a94c134b48d4a41cb806ef1f61d4~tplv-k3u1fbpfcp-zoom-1.image) + 翻頁按鈕的快速點選,觸發了瀏覽器的雙擊快速選擇: [](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/da77c284cd0f4aafb183a5667c5cf32c~tplv-k3u1fbpfcp-watermark.image) 對於這種場景,我們需要把不可被選中元素設定為不可被選中,利用 CSS 可以快速的實現這一點: ```CSS { -webkit-user-select: none; /* Safari */ -ms-user-select: none; /* IE 10 and IE 11 */ user-select: none; /* Standard syntax */ } ``` 這樣,無論點選的頻率多快,都不會出現尷尬的內容選中: ![btn-click-unselect](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db6252ae280b4a07902fa9925854d842~tplv-k3u1fbpfcp-zoom-1.image) ### 跳轉優化 現階段,單頁應用(Single Page Application)的應用非常廣泛,Vue 、React 等框架大行其道。但是一些常見的寫法,也容易衍生一些小問題。 譬如,點選按鈕、文字進行路由跳轉。譬如,經常會出現這種程式碼: ```Javascirpt