質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

7回答

19266閲覧

「普通のクリック」と「別タブ/ウィンドウで開くクリック」を区別したい

sounisi5011

総合スコア697

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

2グッド

2クリップ

投稿2015/07/20 18:58

編集2015/08/14 06:29

JavaScriptでリンクをクリックしページを移動しようとする操作は、通常clickイベントで検出します。

例えば、メニューのページへのリンクをクリックしたらページ移動せず、現在のページ内でメニューを表示する場合などにこのような手法が用いられます。
この場合、JavaScriptが利用できない場合や「右クリック→新しいタブ/ウィンドウで開く」を実行した場合には本来のページ移動が行われ、メニューのみのページが開かれることになります。

しかし、clickイベントを検出している影響で、別タブで開くためのクリックも普通のクリックと一緒に扱われてしまいます。
上述した例の場合、メニューへのリンクを「Ctrl+クリック」(別タブで開く)や「Shift+クリック」(別ウィンドウで開く)、「中クリック」(別タブで開く)した場合、別のタブ/ウィンドウで開くという期待する操作が実行されず、メニューはページ内で展開されてしまいます。

これを解決するには、普通のページ移転に使用するただのクリックと、「Ctrl+クリック」等、別のタブ/ウィンドウで開く為のクリックをclickイベントで区別しなくてはなりません。
clickイベントで、普通のクリックと、別のタブ/ウィンドウで開く為のクリックを区別する良い方法はありますか?

flat, newcre👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

自己解決

MediaWikiのMedia Viewerがまさにこの質問で求める動作をしていたためデバッグを行ってみたところ、以下の処理により判定を行っていました。

JavaScript

1/* 2 * jQueryが内部的に行う`event.which`プロパティの定義 3 * https://github.com/jquery/jquery/blob/3.3.1/src/event.js#L636-L662 4 */ 5var button = event.button; 6// Add which for click: 1 === left; 2 === middle; 3 === right 7// Note: button is not normalized, so don't use it 8if (!event.which && button !== undefined) { 9 event.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); 10} 11 12/* 13 * 判定箇所 14 * https://github.com/wikimedia/mediawiki-extensions-MultimediaViewer/blob/6b83fca574e3dcc2fa4526117f88940dcfc06f30/resources/mmv/mmv.bootstrap.js#L431-L434 15 */ 16if ((event.button !== 0 && event.which !== 1) || event.altKey || event.ctrlKey || event.shiftKey || event.metaKey) { 17 // 別タブ/ウィンドウで開くクリック 18} else { 19 // 普通のクリック 20}

変数eventは、対象のイベントのイベントオブジェクトです。
判定としては、event.buttonまたはevent.whichで「左クリック以外」かの判定と、CtrlやShift等の特殊キーが押下されているかをORで判定していました。

MediaWikiは、世界で5番目に人気のあるウェブサイトWikipediaで使用されているシステムです。
当然、より多くのユーザに対応するため、様々な環境で検証を行い、動作を確認しているコードのはずです。
よって、信頼性は十分であり、「普通のクリック」と「別タブ/ウィンドウで開くクリック」を区別する方法として、これが適切であると考えます。


ちなみに、IE8以下のInternet Explorerでは、mousedown, mouseup, mousemoveイベント以外の場合は、どのようなクリックであってもevent.buttonの値が0になってしまいます。

jQuery で 右クリックと左クリックを判別 - galife

ちなみに、clickイベント時、IE8 だと button プロパティが 0 にしかならないので使えない…

button property (Internet Explorer)

This property is used with the onmousedown, onmouseup, and onmousemove events. For other events, it defaults to 0 regardless of the state of the mouse buttons.

このため、clickイベントではクリックの種類を判定できず、利用できません。

既にセキュリティサポートすら切れた古の遺産たるIE8以下を考慮する状況は限られると思います。しかし、もしIE8以下でも動く処理が必要な場合は、クリックをmousedownイベントやmouseupイベントで検知するようにしましょう。


また、仕様ではevent.whichプロパティは削除されており、代わりにevent.buttonプロパティとevent.buttonsプロパティの使用が推奨されています。

MouseEvent.which - Web APIs | MDN

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

The standard alternatives to this property are MouseEvent.button and MouseEvent.buttons.

event.whichは今後ブラウザからも消えていくプロパティです。
しかし、jQueryでは逆にevent.buttonよりevent.whichの使用を推奨する記述があり、このままでは今後のWeb標準に対応できません。

event.which | jQuery API Documentation

Use event.which instead of event.button.

この事を視野に入れた、更なる修正が必要かもしれません。

投稿2015/07/29 20:05

編集2018/06/15 11:38
sounisi5011

総合スコア697

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単に Ctrl や Shift などが押されているかどうかだけならイベントオブジェクトで検出できると思いますが、

lang

1 document.getElementById('link').addEventListener('click', function(ev){ 2 if (ev.altKey || ev.shiftKey || ev.ctrlKey) { 3 return; 4 } 5 ev.preventDefault(); 6 console.log(ev); 7 }, false);

普通のクリックと、別のタブ/ウィンドウで開くためのクリックは、ブラウザの設定によると思うので、検出は難しいと思います(アドオンとかで変えられそうなので)。

投稿2015/07/20 23:51

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/11/30 03:49 編集

> 普通のクリックと、別のタブ/ウィンドウで開くためのクリックは、ブラウザの設定によると思うので、検出は難しいと思います(アドオンとかで変えられそうなので)。 まさにそこが、この動作を容易に実現できない理由であり、ここで質問した理由でもあります。 左クリックの判定や、Ctrlキーなどはイベントオブジェクトで判別できるのですが…質問本文にない他の操作等は考慮しきれるかどうか… アドオンに関しては利用者の自己責任とも考えられるので対応は見送りますが、ブラウザのデフォルトの機能として備わる「特殊なクリック」は正しく判別したいです。
guest

0

大抵のブラウザの設定では、左クリックは開く、中クリックは新しいウィンドウで開くになっていることと思います。
そこで、そうでない設定をしている人達は置いておいて、中クリックを新しいタブで開くためのものとして扱うのはどうでしょう。
event.button - MDN
event.button==0なら左クリック、event.button==1なら中クリックです。

ブラウザが設定をJavaScriptに知らせる機能というのは見つかりませんでした。どうしても設定を知りたいなら、ユーザーがどのイベントを起こしたら同時に新しいウィンドウが開いているかを監視すればできると思います。

投稿2015/07/24 14:25

編集2015/07/24 14:28
f_acid

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

遷移後にhistory.lengthを見るというのはどうでしょうか

投稿2015/07/21 01:20

hello-world

総合スコア1342

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/07/21 01:30

移転する"前"のクリックイベントの段階で判定する事が目的です。
guest

0

こういうことでしょうか?

ttp://www.programming-magic.com/20090127231544/

投稿2015/07/20 23:49

shigeo.h

総合スコア90

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/07/21 01:34

このあたりの情報についてはあらかた調べてあります。 そしてこれらの情報を合わせれば、「Ctrl+クリック」、「Shift+クリック」、「中クリック」を判別する事そのものは可能です。 ですが、この問題の本質はそこではありません。 質問に書いた操作はあくまで例に過ぎず、これ以外の「別のタブ/ウィンドウで開く為のクリック」が存在する可能性があります。 これを正しく識別することが本質問の求める要件です。
guest

0

リファラ(document.referrer)から、ページ遷移を判定すれば実現できます。

投稿2015/07/20 23:47

LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/07/21 01:25

移転する"前"のクリックイベントの段階で判定する事が目的です。 ただ、実際に移転した後に判定する方法が一番確実であるのも確かです。
guest

0

同じウインドウ内で遷移
location.href=URL

別タブで表示
window.open(URL, '_blank')

…ということでしょうか。

投稿2015/07/20 19:44

yu-ri

総合スコア634

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sounisi5011

2015/07/20 22:12 編集

違います。 addEventListener等で設定するclickイベントで、普通の「ページ移転クリック」と質問に書いた「別のタブ/ウィンドウで開く為のクリック」を区別したいということです。
zabu

2016/11/17 01:16

質問を正しく理解できていない
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問