2022年6月19日

マウスイベント

この章では、マウスイベントとそのプロパティについて詳しく説明します。

注意:このようなイベントは、「マウスデバイス」だけでなく、互換性のためにエミュレートされているスマートフォンやタブレットなどの他のデバイスからも発生する可能性があります。

マウスイベントの種類

これらのイベントの一部はすでに見てきました

mousedown/mouseup
要素の上でマウスボタンがクリック/リリースされます。
mouseover/mouseout
マウスポインタが要素の上/外に出ます。
mousemove
要素上でのマウスの移動ごとに、そのイベントがトリガーされます。
click
マウスの左ボタンが使用されている場合、同じ要素上でmousedownの後にmouseupが発生するとトリガーされます。
dblclick
短時間内に同じ要素を2回クリックするとトリガーされます。最近はめったに使用されません。
contextmenu
マウスの右ボタンを押すとトリガーされます。コンテキストメニューを開く方法は他にもあります。たとえば、特別なキーボードキーを使用すると、その場合にもトリガーされるため、正確にはマウスイベントではありません。

…他にもいくつかのイベントがあります。それらについては後で説明します。

イベントの順序

上記のリストからわかるように、ユーザーアクションによって複数のイベントがトリガーされる場合があります。

たとえば、左ボタンをクリックすると、ボタンが押されたときに最初にmousedownがトリガーされ、ボタンが離されたときにmouseupclickがトリガーされます。

1つのアクションで複数のイベントが開始される場合、それらの順序は固定されます。つまり、ハンドラはmousedownmouseupclickの順序で呼び出されます。

下のボタンをクリックすると、イベントが表示されます。ダブルクリックも試してください。

以下のテストスタンドでは、すべてのマウスイベントが記録され、イベント間に1秒以上の遅延がある場合は、水平線で区切られます。

また、マウスボタンを検出できるbuttonプロパティが表示されます。以下で説明します。

マウスボタン

クリック関連のイベントには、常に正確なマウスボタンを取得できるbuttonプロパティがあります。

通常、clickイベントとcontextmenuイベントには使用しません。前者は左クリックでのみ発生し、後者は右クリックでのみ発生するためです。

一方、mousedownハンドラとmouseupハンドラはevent.buttonが必要になる場合があります。これらのイベントはどのボタンでもトリガーされるため、buttonを使用すると「右mousedown」と「左mousedown」を区別できます。

event.buttonの可能な値は次のとおりです。

ボタンの状態 event.button
左ボタン(プライマリ) 0
中央ボタン(補助) 1
右ボタン(セカンダリ) 2
X1ボタン(戻る) 3
X2ボタン(進む) 4

ほとんどのマウスデバイスには左右のボタンしかないため、可能な値は0または2です。タッチデバイスも、タップすると同様のイベントを生成します。

また、現在押されているすべてのボタンを整数として持つevent.buttonsプロパティがあり、ボタンごとに1ビットです。実際には、このプロパティはめったに使用されません。必要な場合は、MDNで詳細を確認できます。

廃止されたevent.which

古いコードでは、ボタンを取得するための古い非標準の方法であるevent.whichプロパティを使用している場合があります。可能な値は次のとおりです。

  • event.which == 1 – 左ボタン
  • event.which == 2 – 中央ボタン
  • event.which == 3 – 右ボタン

現時点では、event.whichは廃止されているため、使用しないでください。

修飾子:shift、alt、ctrl、meta

すべてのマウスイベントには、押された修飾キーに関する情報が含まれています。

イベントプロパティ

  • shiftKeyShift
  • altKeyAlt(Macの場合はOpt
  • ctrlKeyCtrl
  • metaKey:Macの場合はCmd

イベント中に対応するキーが押された場合、それらはtrueになります。

たとえば、以下のボタンはAlt+Shift +クリックでのみ機能します

<button id="button">Alt+Shift+Click on me!</button>

<script>
  button.onclick = function(event) {
    if (event.altKey && event.shiftKey) {
      alert('Hooray!');
    }
  };
</script>
注意:Macでは通常、Ctrlの代わりにCmdです

WindowsとLinuxには、修飾キーAltShiftCtrlがあります。Macには、プロパティmetaKeyに対応するCmdがもう1つあります。

ほとんどのアプリケーションでは、Windows / LinuxでCtrlを使用する場合、MacではCmdが使用されます。

つまり、WindowsユーザーがCtrl+EnterまたはCtrl+Aを押す場合、MacユーザーはCmd+EnterまたはCmd+Aなどを押します。

そのため、Ctrl +クリックなどの組み合わせをサポートする場合、MacではCmd +クリックを使用するのが理にかなっています。これはMacユーザーにとってより快適です。

MacユーザーにCtrl +クリックを強制したい場合でも、それは少し難しいです。問題は、Ctrlを押した左クリックは、MacOSでは*右クリック*と解釈され、Windows / Linuxのようにclickではなくcontextmenuイベントが生成されることです。

そのため、すべてのオペレーティングシステムのユーザーが快適に感じられるようにするには、ctrlKeyと一緒にmetaKeyを確認する必要があります。

JSコードの場合、これはif(event.ctrlKey || event.metaKey)を確認する必要があることを意味します。

モバイルデバイスもあります

キーボードの組み合わせは、ワークフローへの追加として適しています。そのため、訪問者がキーボードを使用する場合、それらは機能します。

ただし、デバイスにキーボードがない場合、修飾キーなしで操作する方法が必要です。

座標:clientX / Y、pageX / Y

すべてのマウスイベントは、2種類の座標を提供します

  1. ウィンドウ相対:clientXおよびclientY
  2. ドキュメント相対:pageXおよびpageY

これらの違いについては、座標の章ですでに説明しました。

要するに、ドキュメント相対座標pageX / Yはドキュメントの左上隅からカウントされ、ページがスクロールされても変化しませんが、clientX / Yは現在のウィンドウの左上隅からカウントされます。ページがスクロールされると、それらは変化します。

たとえば、サイズ500x500のウィンドウがあり、マウスが左上隅にある場合、ページのスクロール方法に関係なく、clientXclientY0になります。

マウスが中央にある場合、ドキュメントのどの場所にあるかに関係なく、clientXclientY250になります。この点で、それらはposition:fixedに似ています。

入力フィールドにマウスを移動して、clientX / clientYを確認します(例はiframeにあるため、座標はそのiframeに対して相対的です)

<input onmousemove="this.value=event.clientX+':'+event.clientY" value="Mouse over me">

mousedownでの選択の防止

マウスのダブルクリックには、一部のインターフェースで邪魔になる可能性のある副作用があります。テキストが選択されます。

たとえば、以下のテキストをダブルクリックすると、ハンドラに加えてテキストが選択されます

<span ondblclick="alert('dblclick')">Double-click me</span>

マウスの左ボタンを押して、離さずにマウスを動かすと、それも選択されますが、多くの場合、これは望ましくありません。

選択を防ぐ方法は複数あり、選択と範囲の章で読むことができます。

この特定のケースでは、最も合理的な方法は、mousedownでブラウザのアクションを防ぐことです。これにより、これらの両方の選択が防止されます

Before...
<b ondblclick="alert('Click!')" onmousedown="return false">
  Double-click me
</b>
...After

これで、太字の要素はダブルクリックで選択されなくなり、左ボタンを押しても選択が開始されません。

注意:その中のテキストはまだ選択可能です。ただし、選択はテキスト自体ではなく、テキストの前または後で開始する必要があります。通常、これはユーザーにとって問題ありません。

コピーの防止

ページの内容をコピーペーストから保護するために選択を無効にする場合は、別のイベント:oncopyを使用できます。

<div oncopy="alert('Copying forbidden!');return false">
  Dear user,
  The copying is forbidden for you.
  If you know JS or HTML, then you can get everything from the page source though.
</div>

<div>内のテキストをコピーしようとすると、デフォルトのアクションoncopyが防止されるため、機能しません。

確かにユーザーはページのHTMLソースにアクセスでき、そこからコンテンツを取得できますが、誰もがその方法を知っているわけではありません。

まとめ

マウスイベントには、次のプロパティがあります

  • ボタン:button

  • 修飾キー(押された場合にtrue):altKeyctrlKeyshiftKey、およびmetaKey(Mac)。

    • Ctrlを処理する場合は、Macユーザーを忘れないでください。通常はCmdを使用するため、if(e.metaKey || e.ctrlKey)を確認することをお勧めします。
  • ウィンドウ相対座標:clientX / clientY

  • ドキュメント相対座標:pageX / pageY

mousedownのデフォルトのブラウザアクションはテキスト選択です。インターフェースに適していない場合は、それを防ぐ必要があります。

次の章では、ポインタの動きを追跡するイベントと、その下の要素の変更を追跡する方法について詳しく説明します。

タスク

重要度:5

ファイルマネージャーのように、要素を選択できるリストを作成します。

  • リスト要素をクリックすると、その要素のみが選択され(クラス.selectedが追加され)、他のすべての要素の選択が解除されます。
  • Ctrl(Macの場合はCmd)を押しながらクリックすると、要素の選択が切り替えられますが、他の要素は変更されません。

デモ

追伸 このタスクでは、リスト項目はテキストのみであると想定できます。ネストされたタグはありません。

追伸 クリック時のテキストのネイティブブラウザ選択を防ぎます。

タスクのサンドボックスを開きます。

チュートリアルマップ

コメント

コメントする前に読んでください…
  • 改善の提案がある場合は、コメントする代わりに、GitHubのIssueを作成するか、プルリクエストを送信してください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • 短いコードを挿入するには<code>タグを使用し、複数行の場合は<pre>タグで囲み、10行を超える場合はサンドボックス(plnkrjsbincodepenなど)を使用してください。