我們許多專案,都會有網頁設計師設計版型,然後再交由前端工程師套版。不過有很多版型,都會留有 <a href="#"></a>
這樣的空連結,比較常見的用途都是在「多層次選單」的上層連結。但這樣的連結,在套用至多頁面路由的 SPA 應用程式中時,就會出現問題。由於 SPA 網頁在設計的時候,都會套用 <base href="...">
元素,設定網頁中所有連結的基礎位址 (Base URL),當使用者點擊 <a href="#">
這樣的連結時,就會導致網頁重新整理!本篇文章將解說幾個可能的解決方案。
避免觸發超連結事件的幾種做法
我們一般比較常見的寫法有幾種:
-
直接使用 #
當作超連結
這種技巧對於靜態版型還可行,許多網頁設計師也很習慣這樣寫,但是當使用者點擊連結後,卻會在目前網址後方加上一個 #
符號。一來,我個人相當不喜歡這種作法,因為網址會發生改變;二來,這種寫法會讓 SPA (單一頁面應用程式) 的路由發生異常,所以應該避免。
-
使用特殊的 javascript:void(0)
當作超連結
這種寫法通常是前端工程師以及對 UX 特別要求的設計師愛用,原因無他,就是網址列不會出現怪怪的 #
符號。這種寫法同時也對 SPA 網頁應用程式相當友善,所以推薦使用。但唯一的缺點,就是比 #
多打太多字了!
-
使用特殊的 javascript:;
當作超連結
這種寫法跟 javascript:void(0)
如出一轍,但硬是少打了 6 個字元,如果學會他,你這輩子可能有機會打超過 1000 次這種連結,就可以少打 6000 個按鍵,不無小補啦。
透過 Angular 自訂指令元件 (Directive) 實現
身為前端工程師,在 JavaScript 可以控制到的地方,幾乎沒有不可能的事。所以我們當然可以透過 Angular 自訂 Directive 來將許多版型常見的 <a href="#">
連結,自動修復成沒有問題的連結,好讓設計師們不用改變長久以來的設計習慣,繼續使用 #
當成預設超連結。
你可以先建立一個 a.directive.ts
檔案,放在 /src/app/
目錄下:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: 'a[href="#"]'
})
export class ADirective {
@HostListener('click', ['$event'])
onClick(e) {
e.preventDefault();
}
}
接著,再到 AppModule
模組中,將上述 ADirective
元件類別加入到 @NgModule
裝飾器的 declarations
屬性中,如下範例:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { ADirective } from './a.directive';
@NgModule({
...
declarations: [AppComponent, HelloComponent, ADirective],
bootstrap: [AppComponent]
...
})
export class AppModule { }
就這樣簡單兩個步驟,即可讓你所有的 Angular 元件樣板,不用再害怕出現有 #
超連結的情況。
相關連結