如何處理 Angular 單頁面應用裡的 a 標籤,避免點選後重新載入整個應用
問題描述
客戶已經實現了一些“free html”元件,它是 HTML 的標題和包裝器,與 OCC 響應一起作為內容。
<div [innerHTML]="data?.content | safeHtml"></div>
這個 HTML 裡包含了 anchor element:
<div class="starItem"> <a href="https://www.customer.com/de/jerry/c/010101"> <div class="starImg" style="background-image:url(https://media.customer.com/medias/webmaster/homepage/images/jerry/star1.jpg);"></div> <p>jerry</p> </a> </div>
不幸的是這個 a 標籤導致頁面重新載入並且不使用 Angular 路由,換言之,它會終止 SPA 的狀態。
如何避免這種行為?比如實現一些偵聽器並檢查點選是否應該改為執行一些路由器操作並 prevent default?
解決方案
https://github.com/SAP/spartacus/pull/15317/commits
解決方案的詳細實現:
-
在 Angular module 裡,匯入
RouterModule
-
使用 @HostListener,攔截元素的 click 事件。
當 handleClick 方法觸發時,說明宿主元素已經被點選了。此時判斷 event 物件的型別是否為 HTMLAnchorElement
然後使用 event 物件的 preventDefault 阻止 a 標籤頁造成的整個應用重新載入,然後使用 Angular route 的 navigate
進行頁面內部跳轉即可。
相關知識點
- Event 介面的 preventDefault() 方法告訴 user agent,如果事件沒有得到顯式處理,則不應像通常那樣執行其預設操作。在我們這個例子,即阻止 a 元素被點選後觸發的頁面 reload 動作。
事件繼續像往常一樣傳播,除非它的事件偵聽器之一呼叫 stopPropagation() 或 stopImmediatePropagation(),其中任何一個呼叫都會立即終止事件的傳播。
-
HTMLAnchorElement: HTMLAnchorElement 介面表示超連結元素,並提供特殊的屬性和方法來操縱此類元素的佈局和表示。該介面對應於
<a>
元素。 注意不要與<link>
混淆,後者由HTMLLinkElement
表示。 -
route: 定義單個路由的配置物件。 一組路由收集在 Routes 陣列中以定義 Router 配置。路由器嘗試使用此物件中定義的配置選項將給定 URL 的段與每個路由進行匹配。本例我們使用了 router 的
navigate
方法進行單頁面應用的內部導航。