Angular で accesskey 属性を使ってキーボードからボタンを押下する

拙作の Angular アプリ「Neo's Hatebu」を、個人でちょくちょく使っては手直ししている。

このアプリは、はてブのエントリごとに「削除する」ボタンが付いていて、一度読んだエントリを非表示にできるというモノ。スマホで見る時は「削除する」ボタンをポチポチタップしながら、興味のない記事・目を通した記事を消していっている。

PC で操作するときも同様に、マウスで「削除する」ボタンをカチカチクリックしながら記事を消しているのだが、最近どうもこの「クリック操作」が面倒臭く感じるようになってきた。

せっかく PC なので、キーボードで操作したいじゃないか。

ということで、ボタンに accesskey 属性を付与して、キーボードショートカットで操作できるようにしてみる。

自分は記事一覧を1件目から順に見て削除していくので、特定のアクセスキーを押すと記事の1件目がどんどん消していける仕組みを考えた。

Angular の場合、エントリ一覧を表示している *ngFor の内部で index を確認し、1件目を表示している場合のみ、ボタンに accesskey 属性を付与するように実装してやった。

<div *ngFor="let item of items; index as i">
  <ng-template *ngIf="i === 0; else others">
    <button type="button" (click)="removeItem(item.id)" accesskey="d">削除する</button>
  </ng-template>
  <ng-template #others>
    <button type="button" (click)="removeItem(item.id)">削除する</button>
  </ng-template>
  
  <p>{{ item.name }}</p>
</div>

イメージはこんな感じ。*ngIfelse 【テンプレート名】 というイディオムを使って分岐させているが、このレベルであれば単純に

<button type="button" (click)="removeItem(item.id)" *ngIf="i === 0" accesskey="d">削除する</button>
<button type="button" (click)="removeItem(item.id)" *ngIf="i !== 0"              >削除する</button>

と並べてあげて、accesskey の有無しか違いがないことを表現してやっても良いかもしれない。

このようなボタンを含む要素が *ngFor 属性によってループし、複数表示されている。accesskey 属性によってクリックイベントが発生するので、(click)="removeItem()" 関数が発火する。この removeItem() 関数では配列 items から指定の要素を削除しているテイなので、1件目が選ばれたら、それまで2件目に表示されていたモノが1件目として再描画され、accesskey がまた付与されるということになる。こういう動きなので、アクセスキーを連打すれば、1件目の記事が1つずつ削除されていくことになる。

コレで思ったとおりのことができた。