web-dev-qa-db-ja.com

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

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

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

これは可能ですか?

124
TM.

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は、現在押されているボタンのビットマスクを使用します。

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

そして、覚えておいてください:IEは、「event」と呼ばれるグローバルイベントオブジェクトを使用します。

ちなみに、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-styleスタイルのコードを引き継いだ理由がわかりません。イベントハンドラをドキュメントに直接添付する方が適切です。

135
Eugene Lazutkin

これは古い質問であり、ここでの答えは、ボタンが押されたかどうかを追跡するためにmousedownおよびmouseupを使用することを主に支持しているようです。しかし、他の人が指摘しているように、mouseupはブラウザ内で実行されたときにのみ起動し、ボタンの状態を追跡できなくなる可能性があります。

ただし、 MouseEvent (now)は、現在プッシュされているボタンを示します。

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

documentに登録すると、mousemoveはカーソルがブラウザーに再び入るとすぐに起動するため、ユーザーが外部にリリースすると、マウスが内部に戻るとすぐに状態が更新されます。

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

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がゲームを終了した場合、これが簡単になります。

22
Jono Job

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

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.
}
17
paxdiablo

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

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

12
alfred

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

<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イベントでその状態を読み取る方法が必要なだけです。そのために、デフォルトのカーソルが「auto」であるという事実にチートして依存する必要があり、それを「default」に変更するだけです。これがデフォルトで自動選択されます。

GetComputedStyleによって返されるオブジェクトで、ページの外観を混乱させることなくフラグとして使用できるものなら何でも使用できます。ボーダの色。

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

6
Martin

次のスニペットは、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);
}
4
Jake Devine

短くて甘い

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

Bodyタグに追加:

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

次に、down1に等しい場合、myfunction()をテストして実行します。

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

@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
}
2
Jake Devine

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

2
Thomas Hansen

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
Marcin Żurek

既存のマウスイベントハンドラーを使用して複雑なページ内で作業している場合、capture(バブルの代わりに)でイベントを処理することをお勧めします。これを行うには、addEventListenerの3番目のパラメーターを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の代わりにドキュメント(またはウィンドウ)にハンドラーを追加することは、マウスアップイベントウィンドウ外が引き続き記録されるようにするために重要です。

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
NVRM

@Jackが言ったように、ブラウザウィンドウの外でmouseupが発生した場合、それを認識しません...

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

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

残念ながら、これらのケースの1つではmouseupイベントを取得できません。

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

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

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

複数のマウスボタンを処理する方法がわかりません。ウィンドウの外でクリックを開始する方法があり、マウスをウィンドウに持ってくると、そこでもおそらく正しく動作しません。

0
David