JavaScript:マウスボタンが押されているかどうかを確認しますか?
-
11-07-2019 - |
質問
JavaScriptでマウスボタンが現在押されているかどうかを検出する方法はありますか?
「mousedown」について知っています。イベントですが、それは私が必要なものではありません。マウスボタンが押されてからしばらくしてから、まだボタンが押されているかどうかを検出できるようにします。
これは可能ですか?
解決
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 for middle
- および上記の任意の組み合わせ、たとえば、左+中央に5
それに応じてコードを調整してください!演習として残します。
覚えておいてください:IEは&#8230;というグローバルイベントオブジェクトを使用します。 &quot; event&quot;。
IEには、あなたの場合に役立つ機能があります。他のブラウザが「ボタン」を送信するときマウスボタンイベント(onclick、onmousedown、およびonmouseup)に対してのみ、IEはonmousemoveでも送信します。そのため、ボタンの状態を知る必要があるときにonmousemoveのリッスンを開始し、ボタンを取得したらすぐにevt.buttonを確認できます&#8212;これで、どのマウスボタンが押されたかがわかりました:
// for IE only!
document.body.onmousemove = function(){
if(event.button){
// aha! we caught a feisty little sheila!
}
};
もちろん、彼女が死んで遊んでいない場合は何も得られません。
関連リンク:
更新#1 :document.bodyスタイルのコードを引き継いだ理由がわかりません。イベントハンドラをドキュメントに直接添付することをお勧めします。
他のヒント
これは古い質問です。ここでの答えは、ほとんどが mousedown
と mouseup
を使用してボタンが押されたかどうかを追跡することを支持しているようです。しかし、他の人が指摘したように、 mouseup
はブラウザ内で実行されたときにのみ起動し、ボタンの状態を追跡できなくなる可能性があります。
ただし、 MouseEvent (現在)は、どのボタンが現在プッシュ済み:
- すべての最新ブラウザ(Safariを除く)では、
を使用しますMouseEvent.buttons
- Safariの場合、
MouseEvent.which を使用しますcode>
(buttons
はSafariでは未定義)注: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がゲームを終了した場合、またはこれが簡単になります。
これに対する最善のアプローチは、次のようにマウスボタンの状態を独自に記録することだと思います。
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.
}
解決策は良くありません。 「マウスダウン」できるドキュメント上で、「mouseup」ブラウザの外で、この場合、ブラウザはまだマウスがダウンしていると考えます。
唯一の良い解決策はIE.eventオブジェクトを使用することです。
これは古い投稿であることは知っていますが、マウスアップ/ダウンを使用したマウスボタンの追跡は少し不格好だと思ったため、一部のユーザーにアピールする代替案を見つけました。
<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」であるという事実をチートして信頼する必要がありました。それを&quot; default&quot;に変更するだけです。これはデフォルトで自動選択されます。
getComputedStyleによって返されるオブジェクトで、ページの外観を混乱させることなくフラグとして使用できるものなら何でも使用できます。ボーダーカラー。
:activeセクションで独自のユーザー定義スタイルを設定したかったのですが、動作させることができませんでした。可能であればもっといいでしょう。
次のスニペットは、「doStuff」を実行しようとします。 mouseDownイベントがdocument.bodyで発生してから2秒後に機能します。ユーザーがボタンを持ち上げると、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);
}
短くて甘い
これまでの答えがどれも役に立たなかった理由はわかりませんが、ユーレカの瞬間にこの解決策を思いつきました。動作するだけでなく、最もエレガントです:
bodyタグに追加:
onmouseup="down=0;" onmousedown="down=1;"
次に、 down
が 1
と等しい場合、 myfunction()
をテストして実行します:
onmousemove="if (down==1) myfunction();"
@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とMouseUpを処理し、それを追跡するためのフラグまたは何かを設定する必要があります。
jQueryを使用して、次のソリューションは「ページからドラッグしてからケースをリリース」まで処理します。
$(document).mousedown(function(e) {
mouseDown = true;
}).mouseup(function(e) {
mouseDown = false;
}).mouseleave(function(e) {
mouseDown = false;
});
複数のマウスボタンの処理方法がわかりません。 ウィンドウの外でクリックを開始する方法があり、マウスをウィンドウに持って行くと、おそらくそこでも正しく動作しません。
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();
});
@Jackが言ったように、 mouseup
がブラウザウィンドウの外で発生した場合、それを認識しません...
このコードは(ほぼ)私のために働いた:
window.addEventListener('mouseup', mouseUpHandler, false);
window.addEventListener('mousedown', mouseDownHandler, false);
残念ながら、これらのケースの1つでは mouseup
イベントを取得できません。
- ユーザーはキーボードのキーとマウスボタンを同時に押し、ブラウザーウィンドウの外でマウスボタンを離してからキーを離します。
- ユーザーが 2つのマウスボタンを同時に押し、1つのマウスボタンを離してから、もう1つをブラウザーウィンドウの外側で離します。
既存のマウスイベントハンドラーを使用して複雑なページ内で作業している場合は、(バブルではなく)キャプチャでイベントを処理することをお勧めします。これを行うには、 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の代わりにドキュメント(またはウィンドウ)にハンドラーを追加することは重要ですb / cこれにより、マウスアップイベントウィンドウ外が引き続き記録されます。
まあ、イベントの後にダウンしているかどうかはチェックできませんが、アップかどうかはチェックできます...アップしていれば..ダウンしていないことを意味します:P lol
つまり、ユーザーがボタンを押して(onMouseDownイベント)...その後、起動しているか(onMouseUp)を確認します。稼働していなくても、必要なことを実行できます。
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;
}
このクロスブラウザバージョンは私にとっては問題なく動作します。