자바 스크립트 : 마우스 버튼이 눌 렸는지 확인?


136

JavaScript에서 마우스 버튼이 현재 작동하지 않는지를 감지하는 방법이 있습니까?

"mousedown"이벤트에 대해 알고 있지만 이것이 필요한 것은 아닙니다. 마우스 버튼을 누른 후에도 여전히 눌려 있는지 감지하고 싶습니다.

이게 가능해?


14
귀하의 질문에 답변이되지 않는 답변을 수락하는 이유. mousedown 및 mouseup 등록이 잘못되었습니다 (브라우저 외부에서 mouseup을해도 여전히 드래그한다고 생각할 수 있으므로). 문제가 발생한
Jack

@ 잭 그것은 내 질문에 대답합니다. 내 질문을 읽고 답을 읽으십시오. 분명히 100 명 이상의 다른 사람들이 그것이 정답이라고 동의합니다.
TM.

4
하지만 알프레드와 다른 8 명은 mouseup과 mousedown을 추적하는 것이 옳지 않다고 말합니다. 정답은 선택한 처리기에서 이벤트 객체를 분석하거나 이벤트 기반 검사 대신 시간 중심 검사가 필요한 경우 모든 마우스 관련 이벤트 (예 : 입력 / 종료)를 분석해야합니다.
Jack

이 질문은 7 년 이상 전에 답변을 받았습니다. 새로운 답변이있을 때 알림을받지 못합니다 (하지만 의견은 제공합니다). 더 나은 답변을 쓰면 커뮤니티는 그것을 최고로 올릴 것입니다. :) 많은 정보가 오래되고 변화가 일어납니다.
TM.

2
@TM. 네크로에 미안하지만 ... 아니, 그 정보는 결코 정상에 오르지 못할 것이다. 자신이 아닌 답변은 일단 수락되면 영원히 최고에 머물러 있습니다. 또한 "오, 너무 많은 사람들이 이것에 투표했다"는 대답이 좋은 것임을 의미하지는 않습니다. 그것은 많은 사람들이 그것을보고, 좋아 보인다고 생각하고, 공감대를 쳤다는 것을 의미합니다.
Fund Monica의 소송

답변:


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는… "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 스타일 코드를 넘겨 받았는지 모르겠습니다. 이벤트 핸들러를 문서에 직접 첨부하는 것이 좋습니다.


1
테스트 후 evt.button은 실제로 IE7 ...
TM에서

5
스크롤 막대에서 원래 마우스 다운이 발생하면 Chrome이 마우스 업 이벤트를 생성하지 않기 때문에 Chrome에서 작동하지 않는다고 생각합니다. 로부터 이 크롬 / 크롬 문제 . 따라서 누군가가 사용하는 스크롤 막대가 있으면 왼쪽 마우스 버튼이 영원히 작동하지 않습니다! (Chrome에서)
KajMagnus

1
나는 당신의 해결책을 좋아하지만 마우스가 다른 응용 프로그램에서 나온다면 ms word라고 말하고 텍스트를 드래그합니다. 마우스가 다운되었음을 어떻게 감지합니까?
Shadrack B. Orina

6
두 번째 예에서 왜 마우스 다운 배열을 증가시키는 지 이해하지 못합니다. 왜 각 버튼에 대한 부울이 아닌 각 버튼에 대한 카운터입니까?
amwinter

2
이것은 정말 인기있는 질문입니다. 이것이 아직 나오지 않은 것에 놀랐지 만 마우스 데이터를 전혀 저장할 필요는 없습니다. event.buttons외부 저장된 변수없이 사용중인 이벤트 트리거에 연결할 수 있습니다 . 나는 새로운 질문을했다. (마우스 업 이벤트가 항상 실행되지 않기 때문에이 솔루션이 작동하지 않기 때문에) 5 분 안에 그 대답을 얻었습니다.
로봇 식 르네상스

32

이것은 오래된 질문이며 여기의 대답은 주로 버튼을 눌렀는지 여부를 추적 mousedown하고 사용하는 것을 옹호하는 것처럼 보입니다 mouseup. 그러나 다른 사람들이 지적했듯이 mouseup브라우저 내에서 수행 할 때만 실행되어 버튼 상태를 잃을 수 있습니다.

그러나 MouseEvent (현재)는 현재 어떤 버튼을 눌렀 는지 나타냅니다.

  • 모든 최신 브라우저 (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에서 게임을 시작하면 더 쉬워집니다.


6
이 코드는 기본 버튼 만 눌렀는지 확인하고 다른 모든 버튼을 누르지 않아야합니다. (예를 들어 1 차 및 2 차를 모두 누르면, e.buttons1+2=3이므로 e.buttons === 1거짓이됩니다). 기본 버튼이 다운되었는지 확인하고 다른 버튼 상태는 신경 쓰지 않으려면 다음과 같이하십시오.(e.buttons & 1) === 1
AJ Richardson

mousemove 중에 버튼 코드가 ​​'1'이어야하지만 '7'을 생성해야한다고 예상하는 상황이 있습니다. 모든 작업은 Chrome에서 수행됩니다. 누군가 어떤 아이디어가 있습니까?
Vasily Hall

@VasilyHall에 대한 MDN 문서를 보면 기본, 보조 및 보조 버튼이 모두 함께 눌려져 있다고 생각하는 MouseEvent.buttons것 같습니다 7. 왜 그런지 잘 모르겠습니다. 고급 마우스를 사용하고 있습니까? 그렇다면 기본으로 시도해 볼 가치가 있습니다. 진행해야 할 경우 비트 체크 를 사용하여 왼쪽 버튼을 눌렀는지 확인하고 다른 버튼은 무시하십시오. 예. MouseEvent.buttons & 1 === 1.
Jono Job

고맙습니다. 저는 Adobe Illustrator 응용 프로그램에 포함 된 Chrome (ium?)과 같은 특수 브라우저에서 JavaScript를 사용하고 있습니다. 단 하나의 버튼 만 누르면 여러 가지 방법이 조합되어 7로 연결됩니다. . 내 응용 프로그램 내에서 이것이 어떻게 일관성이 있는지 확인하기 위해 대화 형 작업을 용이하게하기 위해 1 또는 7을 확인하고 있습니다. Logitech M570 (또는 기타) 트랙볼 마우스를 사용하지만 일반 브라우저에는 1을 등록하지만 Illustrator에는 7을 올바르게 등록합니다.
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

1
@moala 나는 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 이벤트에서 해당 상태를 읽는 방법 만 있으면됩니다. 이를 위해 기본 커서가 "auto"라는 사실에 속이고 의존해야했습니다. "default"로 변경하면 자동으로 기본적으로 선택됩니다.

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()하십시오 .down1

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

4
당신은 새롭기 때문에 여기서 조금 도와 드리겠습니다. 우선, 글에서 문법을 기억하십시오-아마 당신이 그것을 넣는 것보다 그것을 고치는 데 더 많은 시간을 보냈습니다. 둘째, 귀하의 솔루션은 위에 나열된 다른 버전의 다른 버전 일뿐입니다. 새로운 것은 아닙니다. 셋째, 귀하의 솔루션은 위에서 Thomas Hansen이 제안한 "플래그 사용"이라는 기술을 사용합니다. 다른 솔루션이 효과가없는 이유에 대한 설명을 제공하지 않고 이전 게시물에 게시 할 때 문법을 확인하고 솔루션을 반복하지 않도록주의하십시오.
Zachary Kniebel

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 ()에서 Interval ()을 지워야합니까? 타이머 기능을 0으로 설정하고 타이머를 중지하는 사이에 타이머 기능이 실행되는 것을 조심하고 시간 초과를 200으로 유지합니까? 마찬가지로 onmousedown에서도 마찬가지입니다.
paxdiablo

clearIntervals의 순서는 이벤트 (타이머 포함)가 시작되기 전에 현재 실행 스레드가 완료되므로 차이가 없습니다.
Nathaniel Reinhart 1

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 대신 문서 (또는 창)에 처리기를 추가합니다. b / c 는 창 외부의 mouseup 이벤트 가 계속 기록되도록합니다.


1

MouseEvent API를 사용하여 눌러 진 버튼이 있는지 확인하십시오.

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

귀국 :

하나 이상의 버튼을 나타내는 숫자입니다. 둘 이상의 버튼을 동시에 누르면 값이 결합됩니다 (예 : 3은 1 차 + 2 차입니다).

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

@Jack이 말했듯 mouseup이 브라우저 창 밖에서 발생 하면 알지 못합니다 ...

이 코드는 (거의) 저에게 효과적이었습니다.

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

불행히도, 나는 mouseup그러한 경우 중 하나 에서 이벤트를 얻지 못할 것입니다 .

  • 사용자는 키보드 키와 마우스 버튼을 동시에 누르고 브라우저 창 외부에서 마우스 버튼을 놓은 다음 키를 놓습니다.
  • 사용자는 두 개의 마우스 버튼을 동시에 누르고 , 하나의 마우스 버튼을 놓은 다음 다른 하나는 브라우저 창 외부에서 해제합니다.

-1

글쎄, 당신은 이벤트 후 다운되었는지 확인할 수 없지만, 업인지 여부를 확인할 수는 있습니다.

따라서 사용자가 버튼을 눌렀을 때 (onMouseDown 이벤트) ... 그런 다음이 켜져 있는지 (onMouseUp) 확인합니다. 작동하지 않는 동안 필요한 것을 수행 할 수 있습니다.


2
onMouseUp도 이벤트가 아니십니까? Mouseupup의 "속성"을 어떻게 확인 하시겠습니까? 아니면 오히려 누구의 재산입니까?
Rohit

@Rohit : 속성을 확인하지 않고 이벤트가 발생했음을 나타내는 플래그를 관리합니다 ... 마우스 버튼이 위 또는 아래에 있습니다.
PhiLho

-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.