The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

在 Angular 套版時應注意「空連結」或「多層次選單」的使用

我們許多專案,都會有網頁設計師設計版型,然後再交由前端工程師套版。不過有很多版型,都會留有 <a href="#"></a> 這樣的空連結,比較常見的用途都是在「多層次選單」的上層連結。但這樣的連結,在套用至多頁面路由的 SPA 應用程式中時,就會出現問題。由於 SPA 網頁在設計的時候,都會套用 <base href="..."> 元素,設定網頁中所有連結的基礎位址 (Base URL),當使用者點擊 <a href="#"> 這樣的連結時,就會導致網頁重新整理!本篇文章將解說幾個可能的解決方案。

避免觸發超連結事件的幾種做法

我們一般比較常見的寫法有幾種:

  1. 直接使用 # 當作超連結

    這種技巧對於靜態版型還可行,許多網頁設計師也很習慣這樣寫,但是當使用者點擊連結後,卻會在目前網址後方加上一個 # 符號。一來,我個人相當不喜歡這種作法,因為網址會發生改變;二來,這種寫法會讓 SPA (單一頁面應用程式) 的路由發生異常,所以應該避免。

  2. 使用特殊的 javascript:void(0) 當作超連結

    這種寫法通常是前端工程師以及對 UX 特別要求的設計師愛用,原因無他,就是網址列不會出現怪怪的 # 符號。這種寫法同時也對 SPA 網頁應用程式相當友善,所以推薦使用。但唯一的缺點,就是比 # 多打太多字了!

  3. 使用特殊的 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 元件樣板,不用再害怕出現有 # 超連結的情況。

相關連結

留言評論