JavaScript:マウスボタンが押されているかどうかを確認しますか?


136

JavaScriptで現在マウスボタンが押されているかどうかを検出する方法はありますか?

「マウスダウン」イベントについては知っていますが、それは私が必要としていることではありません。マウスボタンが押された後、それがまだ押されているかどうかを検出できるようにしたいことがあります。

これは可能ですか?


14
質問に答えない回答を受け入れる理由。マウスダウンとマウスアップの登録が間違っている(ブラウザの外でマウスアップして、ドラッグしていると思わせることができるため)。あなたの問題の後に来て、このページに到達することは全く役に立たない
ジャック

@ジャックそれは私の質問に答えます。私の質問を読んでから、答えを読んでください。どうやら他の100人以上がそれが良い答えだと同意している。
TM。

4
ええ..しかし、私、アルフレッド、および他の8人は、マウスアップとマウスダウンを追跡することは正しい方法ではないとあなたに言っています。正解には、選択したハンドラーでのイベントオブジェクトの分析、またはイベント駆動型チェックではなく時間駆動型チェックが必要な場合は、マウスに関連するすべてのイベント(Enter / Exitなど)の分析が含まれます。
Jack

この質問は7年以上前に行われ、回答されました。新しい回答があるときに通知を受け取りません(ただし、コメントは受け付けます)。より適切な回答を書いてください。そうすれば、コミュニティはそれをトップに賛成します:)多くの情報が古くなり、状況が変化します。
TM。

2
@TM。ネクロに申し訳ありませんが...いいえ、その情報がトップになることはありません。非自己回答は、一度受け入れられると、いつまでもトップに留まります。また、「ああ、非常に多くの人々がこれに投票した」というのは、答えが良いものだという意味ではありません。それは、多くの人々がそれを見て、それが問題ないように見え、彼らのために機能しているように見えたために賛成票を投じたことを意味するだけです。
モニカの訴訟に資金を提供

回答:


147

Paxのソリューションについて:ユーザーが意図的または誤って複数のボタンをクリックした場合は機能しません。私がどのように知っているか私に尋ねないでください:-(。

正しいコードは次のようになります。

var mouseDown = 0;
document.body.onmousedown = function() { 
  ++mouseDown;
}
document.body.onmouseup = function() {
  --mouseDown;
}

このようなテストでは:

if(mouseDown){
  // crikey! isn't she a beauty?
}

どのボタンが押されたかを知りたい場合は、mouseDownをカウンターの配列にして、別々のボタンに対して個別にカウントする準備をしてください。

// let's pretend that a mouse doesn't have more than 9 buttons
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
    mouseDownCount = 0;
document.body.onmousedown = function(evt) { 
  ++mouseDown[evt.button];
  ++mouseDownCount;
}
document.body.onmouseup = function(evt) {
  --mouseDown[evt.button];
  --mouseDownCount;
}

これで、どのボタンが正確に押されたかを確認できます。

if(mouseDownCount){
  // alright, let's lift the little bugger up!
  for(var i = 0; i < mouseDown.length; ++i){
    if(mouseDown[i]){
      // we found it right there!
    }
  }
}

上記のコードは、0から始まるボタン番号を渡す標準準拠のブラウザでのみ機能することに注意してください。IEは現在押されているボタンのビットマスクを使用します。

  • 「何も押されていない」の場合は0
  • 左に1
  • 右は2
  • 真ん中は4
  • 上記の任意の組み合わせ。たとえば、左+中央は5

それに応じてコードを調整してください!練習問題として残します。

また、IEは…「イベント」と呼ばれるグローバルイベントオブジェクトを使用します。

ちなみに、IEはあなたの場合に役立つ機能を備えています。他のブラウザがマウスボタンイベント(onclick、onmousedown、onmouseup)に対してのみ「ボタン」を送信する場合、IEはonmousemoveでも送信します。したがって、ボタンの状態を知る必要があるときにonmousemoveのリッスンを開始し、取得したらすぐにevt.buttonを確認できます。これで、どのマウスボタンが押されたかがわかります。

// for IE only!
document.body.onmousemove = function(){
  if(event.button){
    // aha! we caught a feisty little sheila!
  }
};

もちろん、彼女が死んで動いていない場合は何も得られません。

関連リンク:

アップデート#1:document.bodyスタイルのコードを引き継いだ理由がわかりません。ドキュメントに直接イベントハンドラーを添付することをお勧めします。


1
テスト後、evt.buttonは実際にはIE7のmouseemoveには存在しないようです...
TM。

5
スクロールバーで元のマウスダウンが発生した場合、Chromeはマウスアップイベントを生成しないため、これはChromeでは機能しないと思います。から、このクロム/クロムの問題。したがって、誰かが使用するスクロールバーがある場合、マウスの左ボタンは永久に押し下げられます。(Chrome内)
KajMagnus

1
私はあなたの解決策が大好きですが、マウスが別のアプリケーションから来ている場合はどうでしょうか。マウスがダウンしていることをどのように検出しますか?
Shadrack B. Orina 2012

6
2番目の例でマウスダウン配列eltsをインクリメントする理由がわかりません。なぜ各ボタンのブール値ではなく、各ボタンのカウンターですか?
amwinter 2013年

2
これは非常に人気のある質問(および回答)です。これがまだ出ていないことに驚いていますが、マウスのデータを保存する必要はまったくありません。event.buttons外部に保存された変数なしで、使用しているイベントトリガーにプラグインできます。私はまったく新しい質問をしました(私のマウスアップイベントは常に発生するわけではないので、この解決策は私にとってはうまくいきません)と、おそらく5分で答えが得られました。
RoboticRenaissance 2015

32

これは、古い問題であり、ここでは答えはほとんど使用を提唱するようだmousedownmouseup、ボタンが押されているかどうかを追跡するために。しかし、他の人が指摘したように、mouseupはブラウザ内で実行された場合にのみ起動するため、ボタンの状態を追跡できなくなる可能性があります。

ただし、MouseEvent(現在)は、現在押されているボタンを示します。

  • すべての最新のブラウザー(Safariを除く)の場合 MouseEvent.buttons
  • Safariの場合、MouseEvent.which(Safariの場合はbuttons未定義になります)をwhich使用しbuttonsます。注:右クリックと中クリックには異なる番号を使用します。

登録するとdocumentmousemoveできるだけ早くユーザーのリリースは外、状態はすぐに彼らは、マウスの背部の内部などのように更新されますので、場合、カーソルは、ブラウザに再び入るとすぐに発生します。

単純な実装は次のようになります。

var leftMouseButtonOnlyDown = false;

function setLeftButtonState(e) {
  leftMouseButtonOnlyDown = e.buttons === undefined 
    ? e.which === 1 
    : e.buttons === 1;
}

document.body.onmousedown = setLeftButtonState;
document.body.onmousemove = setLeftButtonState;
document.body.onmouseup = setLeftButtonState;

より複雑なシナリオが必要な場合(異なるボタン/複数のボタン/コントロールキー)、MouseEventのドキュメントを確認してください。Safariがゲームを上げたとき、またはそうした場合、これは簡単になるはずです。


6
このコードは、主ボタンのみが押されているかどうかをチェックし、他のすべてのボタンを押さないようにする必要があります。(たとえば、プライマリとセカンダリの両方が押された場合、にe.buttonsなるため1+2=3e.buttons === 1falseになります)。あなたは、主ボタンが押されているかどうかをチェックするが、他のボタンの状態を気にしない場合は、次の操作を行います(e.buttons & 1) === 1
AJリチャードソン

マウスの移動中にボタンのコードを「1」にする必要があると期待している状況がありますが、「7」が生成されます-すべての作業はChromeで行われます。誰かが何か考えがありますか?
Vasily Hall

@VasilyHallのMDNドキュメントを見ると、プライマリボタン、セカンダリボタン、補助ボタンがすべて一緒に押されていると考えられているMouseEvent.buttonsように見え7ます。なぜそうなるのかわかりません。高度なマウスを使用していますか?もしそうなら、おそらくそれは基本的なもので試す価値があります。実行する必要があるだけの場合は、ビット単位のチェックを使用して、左ボタンが押されていることを確認し、他のボタンを無視することができます。例えば。MouseEvent.buttons & 1 === 1
Jono Job

ありがとう、私は特別なブラウザー内でJavaScriptを使用していました:Adobe Illustratorアプリケーション内の埋め込みChrome(ium?)-さまざまなものすべての組み合わせが何らかの方法で7につながると思います。アプリケーション内でこれがどのように一貫しているかを見て、対話性を高めるために1または7のチェックを行っています。追加しますが、私はLogitech M570(またはその他)のトラックボールマウスを使用していますが、1は通常のブラウザーに正しく登録されていますが、7はIllustrator内に正しく登録されています。
Vasily Hall

16

これに対する最善のアプローチは、次のように、マウスボタンの状態を自分で記録することです。

var mouseDown = 0;
document.body.onmousedown = function() { 
    mouseDown = 1;
}
document.body.onmouseup = function() {
    mouseDown = 0;
}

そして、後であなたのコードで:

if (mouseDown == 1) {
    // the mouse is down, do what you have to do.
}

+1、ありがとうございます。これに頼らざるを得ないのではないかと思ったのですが、直接状態を確認できる機能が欲しいと思っていました。
TM。

12
ブール値を使用しない理由はありますか?
moala 2014

1
@moala Intの方がタイピングが少なく、最終的にわずかにパフォーマンスが良いように思えます:jsperf.com/bool-vs-int
Johnathan Elmore

12

解決策は良くありません。ドキュメントで「マウスダウン」し、ブラウザの外で「マウスアップ」することもできます。この場合、ブラウザは引き続きマウスがダウンしていると考えます。

唯一の適切な解決策は、IE.eventオブジェクトを使用することです。


11
私はあなたがどこから来たのかわかりますが、IEでのみ機能するソリューションを持つことも良いソリューションではありません。
TM。

@alfred mousemoveがウィンドウの外にあるかどうかを確認すると役立つ場合があります。If(event.target.nodeName.toLowerCase === 'html')down = 0;
BF

6

私はこれが古い投稿であることを知っていますが、マウスのアップ/ダウンを使用したマウスボタンの追跡が少し不格好だと思ったので、一部の人に魅力的な代替案を見つけました。

<style>
    div.myDiv:active {
        cursor: default;
    }
</style>

<script>
    function handleMove( div ) {
        var style = getComputedStyle( div );
        if (style.getPropertyValue('cursor') == 'default')
        {
            // You're down and moving here!
        }
    }
</script>

<div class='myDiv' onmousemove='handleMove(this);'>Click and drag me!</div>

:activeセレクターは、マウスの上下移動よりもマウスのクリックをより適切に処理します。onmousemoveイベントでその状態を読み取る方法が必要なだけです。そのために、私はカンニングする必要があり、デフォルトのカーソルが「自動」であるという事実に依存し、デフォルトの自動選択である「デフォルト」に変更しました。

getComputedStyleによって返されるオブジェクトでは、ページの外観を混乱させることなくフラグとして使用できる任意のものを使用できます(例:border-color)。

:activeセクションで独自のユーザー定義スタイルを設定したかったのですが、それを機能させることができませんでした。できればもっといいです。


これを共有してくれてありがとう。私はこのアイデアをドラッグアンドドロップのスタイリングロジックに使用していましたが、IEの問題に直面し、追加のロジック
Eyup Yusein

4

次のスニペットは、document.bodyでmouseDownイベントが発生してから2秒後に「doStuff」関数の実行を試みます。ユーザーがボタンを持ち上げると、mouseUpイベントが発生し、遅延した実行がキャンセルされます。

ブラウザーをまたがるイベントのアタッチにはいくつかの方法を使用することをお勧めします。例を簡略化するために、mousedownプロパティとmouseupプロパティを明示的に設定しました。

function doStuff() {
  // does something when mouse is down in body for longer than 2 seconds
}

var mousedownTimeout;

document.body.onmousedown = function() { 
  mousedownTimeout = window.setTimeout(doStuff, 2000);
}

document.body.onmouseup = function() {
  window.clearTimeout(mousedownTimeout);
}

おかげで、これは私が探していた動作とはかなり異なります(私の質問がこれが私がやろうとしていることであることを示しています)。
TM。

3

短くて甘い

以前の回答がどれもうまくいかなかった理由はわかりませんが、ユーレカの瞬間にこの解決策を思いつきました。それは機能するだけでなく、最もエレガントでもあります:

本文タグに追加:

onmouseup="down=0;" onmousedown="down=1;"

次にmyfunction()down等しい場合にテストして実行します1

onmousemove="if (down==1) myfunction();"

4
あなたは新しいので、ここで少し手伝います。まず、投稿の文法に注意してください-おそらく、あなたが入力するよりも多くの時間をかけて修正に費やしました。第二に、あなたの解決策は上にリストされた他のものの単なる別のバージョンです-それは新しいものではありません。3番目に、ソリューションは、「フラグの使用」と呼ばれる手法を使用します。これは、トーマスハンセンが上記で提案したものです。他の解決策がうまくいかなかった理由を説明せずに、文法をチェックし、古い投稿に投稿するときに解決策を繰り返さないように注意してください。
Zachary Kniebel、2012年

5
それが有効であるとあなたがSOに新しいしているように私は、しかし、あなたのソリューションを投票でした
ザカリーKniebel

2

@Paxと私の回答を組み合わせて、マウスが押されていた時間も取得できます。

var mousedownTimeout,
    mousedown = 0;

document.body.onmousedown = function() {
  mousedown = 0; 
  window.clearInterval(mousedownTimeout);
  mousedownTimeout = window.setInterval(function() { mousedown += 200 }, 200);
}

document.body.onmouseup = function() {
  mousedown = 0;
  window.clearInterval(mousedownTimeout);
}

じゃあ後で:

if (mousedown >= 2000) {
  // do something if the mousebutton has been down for at least 2 seconds
}

それは悪い考えではない、ジェイク。mousedownを0に設定する前に、onmouseup()でclearInterval()を実行する必要がありますか?タイマー機能を0に設定してからタイマーを停止してタイムアウトを200のままにするまでの間に、タイマー機能が起動するのではないですか。同様にonmousedownでも。
paxdiablo 2008年

イベント(タイマーを含む)が発生する前に現在の実行スレッドが終了するため、clearIntervalsの順序に違いはありません。
Nathaniel Reinhart

2

あなたは、MouseDownとMouseUpを処理し、フラグを「後で」追跡するためにフラグまたは何かを設定する必要があります... :(


2

既存のマウスイベントハンドラーを使用して複雑なページ内で作業している場合は、(バブルではなく)キャプチャ時にイベントを処理することをお勧めします。これを行うには、の3番目のパラメータをaddEventListenerに設定しますtrue

さらに、event.whichマウスイベントではなく、実際のユーザー操作を処理していることを確認することもできますelem.dispatchEvent(new Event('mousedown'))

var isMouseDown = false;

document.addEventListener('mousedown', function(event) { 
    if ( event.which ) isMouseDown = true;
}, true);

document.addEventListener('mouseup', function(event) { 
    if ( event.which ) isMouseDown = false;
}, true);

ハンドラーをdocument.bodyではなくdocument(またはwindow)に追加します。重要なb / cです。これにより、ウィンドウ外のマウスアップイベントが引き続き記録されます。


1

MouseEvent API を使用して、押されたボタンをチェックします(ある場合)。

document.addEventListener('mousedown', (e) => console.log(e.buttons))

返品

1つ以上のボタンを表す数値。複数のボタンを同時に押すと、値が結合されます(たとえば、3はプライマリ+セカンダリです)。

0 : No button or un-initialized
1 : Primary button (usually the left button)
2 : Secondary button (usually the right button)
4 : Auxilary button (usually the mouse wheel button or middle button)
8 : 4th button (typically the "Browser Back" button)
16 : 5th button (typically the "Browser Forward" button)

0

次のソリューションは、jQueryを使用して、「ページからドラッグしてリリースケース」を処理します。

$(document).mousedown(function(e) {
    mouseDown = true;
}).mouseup(function(e) {
    mouseDown = false;
}).mouseleave(function(e) {
    mouseDown = false;
});

複数のマウスボタンの処理方法がわかりません。ウィンドウの外でクリックを開始する方法があった場合、マウスをウィンドウに近づけると、おそらくここでも正しく機能しません。


0

jQueryの例の下で、マウスが$( '。element')上にある場合、押されたマウスボタンに応じて色が変化します。

var clicableArea = {
    init: function () {
        var self = this;
        ('.element').mouseover(function (e) {
            self.handlemouseClick(e, $(this));
        }).mousedown(function (e) {
            self.handlemouseClick(e, $(this));
        });
    },
    handlemouseClick: function (e, element) {
        if (e.buttons === 1) {//left button
            element.css('background', '#f00');
        }
        if (e.buttons === 2) { //right buttom
            element.css('background', 'none');
        }
    }
};
$(document).ready(function () {
    clicableArea.init();
});

0

@ジャックが言ったmouseupように、ブラウザウィンドウの外で発生した場合、私たちはそれを認識していません...

このコードは(ほとんど)私のために働きました:

window.addEventListener('mouseup', mouseUpHandler, false);
window.addEventListener('mousedown', mouseDownHandler, false);

残念ながら、mouseupこれらのいずれかの場合にはイベントを取得できません。

  • ユーザーがキーボードのキーとマウスボタンを同時に押し、ブラウザウィンドウの外でマウスボタンを離してから、キーを離す。
  • ユーザーが2つのマウスボタンを同時に押し、1つのマウスボタンを離してから、もう一方のボタンをブラウザウィンドウの外側で離します。

-1

ええと、イベント後にダウンしているかどうかは確認できませんが、アップしているかどうかは確認できます。

したがって、ユーザーがボタンを押すと(onMouseDownイベント)...その後、アップかどうか(onMouseUp)を確認します。稼働していない場合でも、必要なことを実行できます。


2
onMouseUpもイベントではありませんか?Mouseupの「プロパティ」をどのように確認しますか?それとも、その所有物ですか?
-Rohit

@Rohit:プロパティをチェックせず、イベントが発生したことを示すフラグを管理します...マウスボタンが上または下にあります。
PhiLho 2008年

-1
        var mousedown = 0;
        $(function(){
            document.onmousedown = function(e){
                mousedown = mousedown | getWindowStyleButton(e);
                e = e || window.event;
                console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
            }

            document.onmouseup = function(e){
                mousedown = mousedown ^ getWindowStyleButton(e);
                e = e || window.event;
                console.log("Button: " + e.button + " Which: " + e.which + " MouseDown: " + mousedown);
            }

            document.oncontextmenu = function(e){
                // to suppress oncontextmenu because it blocks
                // a mouseup when two buttons are pressed and 
                // the right-mouse button is released before
                // the other button.
                return false;
            }
        });

        function getWindowStyleButton(e){
            var button = 0;
                if (e) {
                    if (e.button === 0) button = 1;
                    else if (e.button === 1) button = 4;
                    else if (e.button === 2) button = 2;  
                }else if (window.event){
                    button = window.event.button;
                }
            return button;
        }

このクロスブラウザバージョンは私には問題なく動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.