LoginSignup
153
94

More than 3 years have passed since last update.

ただリンクにしたいときにhref="url"の代わりにonClick="location.href = 'url'"的なことをすると体験を損ねます

Last updated at Posted at 2020-06-09

ただのページ遷移をしたいだけなのに、(主に手抜きという)実装の都合で JS の location.href になってることはありませんか?
実はそれ、体験を損ねているかもしれませんよ。

起こる出来事

マウスのホイールクリック(ミドルクリック)で別のタブで開けません。
Mac にはマウスホイールなんてついてないだろ?
実は Cmd+クリックも同様に別のタブで開けないんですよ。
スマホだったら長押しに相当すると思います。

したがって、意図して別タブで開かせたくない場合を除いて、location.href での遷移は避けるべきです。

厳密には JS の処理内での遷移させるのを避けよう、というべきですね。
なので Router の API を直接コールしての遷移も同様です。

できるだけ <a href="url"> になるようなコードが望ましいです。
SPA(React, Vue, Angular)も同様のコードになるよう意識しましょう。
#補足spa各種フロントエンドフレームワークについて ページの末尾にフロントエンドフレームワークでどう書けばよいか記載しています

location.href になってる理由を考える

遷移先が動的に代わる

<a href=> を動的に書き換えましょう。

同じコンポーネントを使いまわしてるから history.back になってる

可能であれば親コンポーネントからパスを決定したほうがよいです。

親ページじゃなくて遷移元に「戻る」history.back ボタンやりたいじゃん

そういう要望がくるのはわかる。
「でもそれ別のタブで開けないんですよねえ。スマホだったら長押しができないんですよ」というのを説得材料にできないでしょうか。

history.back はブラウザの戻るボタンで同様のことができますし、遷移元によってボタンの遷移先が変わるのは、私はイマイチだと思うんです。
どこからきても前のページに 戻る」より「 どこからきても親のページに 戻る」と設計するほうが良いと思うのですが、最終的には様々な事情によってそうなることもありますね。

ボタンやリンクじゃない

ならいいんじゃないでしょうか。

他の処理をやった後に遷移したい

処理と遷移を別に分けるべきかどうか悩むところですが、1つにまとまっていてもよいケースもあるでしょう。

強い意思を持って location.href を使う

そういうこともあります。存分にやれ。

どういう人がやりがちか

根っからのMacユーザーやラップトップユーザーなど、マウスを使ってない人には馴染みがないのかもしれません。
発見でした。

まとめ

手抜きにはささやかな代償が伴うこともある。

補足SPA(各種フロントエンドフレームワーク)について

React(@rithmetyさん感謝 該当コメント )

<Link to="/path">

有名な React 系のライブラリにはいい感じにしてくれるコンポーネントなどがあります。
それらの内部の実装をまとめた記事を前に書きましたので宣伝します。
SPA で右クリックや shift + クリックなどによる別窓表示に対応させる - Qiita

Vue

<template>
  <!-- vue router -->
  <router-link to="/path">
  <!-- nuxt -->
  <nuxt-link to="path">
</template>

Angular (@seapolisさん感謝 該当コメント

<a [routerLink]="'/hoge'">

ただこの[routerLink]はaタグじゃなくても付けられます。Angular Materialのテーブルの行に対してリンクを付けたいという需要があり、この記事と同様の問題が発生したので、最終的にはJS的に新しいタブで開くよう制御するディレクティブを書きました。
ngx-nat-link - npm

153
94
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
153
94