JavaScript: sprawdź, czy przycisk myszy w dół?

Czy istnieje sposób na wykrycie, czy przycisk myszy jest aktualnie wyłączony w JavaScript?

Wiem o imprezie "mousedown", ale nie tego mi trzeba. Jakiś czas po naciśnięciu przycisku myszy chcę być w stanie wykryć, czy nadal jest wciśnięty.

Czy to możliwe?

Author: TM., 2008-11-27

15 answers

Jeśli chodzi o rozwiązanie Pax: nie działa, jeśli użytkownik kliknie celowo lub przypadkowo więcej niż jeden przycisk. Nie pytaj mnie skąd wiem: - (.

Poprawny kod powinien wyglądać tak:

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

Z takim testem:

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

Jeśli chcesz wiedzieć, który przycisk jest wciśnięty, przygotuj się, aby mouseDown tablicę liczników i policzyć je osobno dla oddzielnych przycisków:

// 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;
}

Teraz możesz sprawdzić, jakie przyciski zostały dokładnie naciśnięte:

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!
    }
  }
}

Teraz bądź ostrzegł, że powyższy kod będzie działał tylko dla przeglądarek zgodnych ze standardami, które przekazują numer przycisku zaczynając od 0 i wyżej. IE używa bitowej maski aktualnie wciśniętych przycisków:

  • 0 dla "nic nie jest wciśnięte"
  • 1 na lewo
  • 2 na prawo
  • 4 dla środka
  • i dowolna kombinacja powyższych, np. 5 dla lewego + środkowego

Więc dostosuj swój kod odpowiednio! Zostawiam to jako ćwiczenie.

I pamiętaj: IE wykorzystuje globalne wydarzenie obiekt o nazwie ... "event".

Nawiasem mówiąc IE ma funkcję przydatną w Twoim przypadku: gdy inne przeglądarki wysyłają "button" tylko dla zdarzeń przycisków myszy (onclick, onmousedown i onmouseup), IE wysyła go również z onmousemove. Możesz więc zacząć słuchać onmousemove, gdy musisz znać stan przycisku i sprawdzić evt.przycisk jak najszybciej - teraz wiesz jakie przyciski myszy zostały naciśnięte:

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

Oczywiście, że nic nie dostaniesz, jeśli ona gra martwą, a nie ruszam się.

Odpowiednie linki:

Update # 1: Nie wiem, dlaczego przeniosłem dokument.body-styl kodu. Lepiej będzie dołączyć procedury obsługi zdarzeń bezpośrednio do dokumentu.

 131
Author: Eugene Lazutkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-08 11:28:15

Myślę, że najlepszym podejściem do tego jest prowadzenie własnego zapisu stanu przycisku myszy, w następujący sposób:

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

A później w Twoim kodzie:

if (mouseDown == 1) {
    // the mouse is down, do what you have to do.
}
 15
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-27 00:48:03

Rozwiązanie nie jest dobre. można "mousedown" na dokumencie, a następnie" mouseup " poza przeglądarką, a w tym przypadku przeglądarka nadal będzie myśleć, że mysz jest wyłączona.

Jedynym dobrym rozwiązaniem jest użycie IE.obiekt zdarzenia.

 12
Author: alfred,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-26 08:14:39

Jest to stare pytanie, A odpowiedzi tutaj wydają się w większości przemawiać za używaniem mousedown i mouseup, aby śledzić, czy przycisk jest wciśnięty. Ale jak zauważyli inni, mouseup będzie uruchamiany tylko wtedy, gdy zostanie uruchomiony w przeglądarce, co może prowadzić do utraty śledzenia stanu przycisku.

Jednak MouseEvent (teraz) wskazuje, które przyciski są aktualnie wciśnięte:

  • dla wszystkich nowoczesnych przeglądarek (z wyjątkiem Safari) używać MouseEvent.buttons
  • dla Safari, użyj MouseEvent.which (buttons będzie niezdefiniowany dla Safari) Uwaga: which używa różnych liczb z buttons dla kliknięć prawym i środkowym.

Przy rejestracji na document, mousemove uruchomi się natychmiast, gdy tylko kursor ponownie uruchomi przeglądarkę, więc jeśli użytkownik zwolni Na Zewnątrz, stan zostanie zaktualizowany, gdy tylko mysz wróci do środka.

Prosta implementacja może wyglądać następująco:

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;

Jeśli wymagane są bardziej skomplikowane scenariusze (różne przyciski / wiele przyciski/klawisze sterujące), sprawdź dokumenty MouseEvent. Kiedy / jeśli Safari podniesie swoją grę, powinno to być łatwiejsze.

 11
Author: Jono Job,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-25 05:58:54

Poniższy fragment spróbuje wykonać funkcję "doStuff" 2 sekundy po wystąpieniu zdarzenia mouseDown w dokumencie.ciało. Jeśli użytkownik podniesie przycisk, nastąpi zdarzenie mouseUp i anuluje opóźnione wykonanie.

Radziłbym użyć jakiejś metody do załączania zdarzeń między przeglądarkami - Ustawianie właściwości mousedown i mouseup zostało wyraźnie zrobione, aby uprościć przykład.

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
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-27 00:34:42

Wiem, że to stary post, ale myślałem, że śledzenie przycisku myszy za pomocą myszy w górę/w dół wydawało się nieco niezgrabne, więc znalazłem alternatywę, która może się spodobać niektórym.

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

Aktywny selektor obsługuje kliknięcie myszką znacznie lepiej niż mysz w górę/w dół, potrzebujesz tylko sposobu odczytu tego stanu w zdarzeniu onmousemove. W tym celu musiałem oszukiwać i polegać na tym, że domyślnym kursorem jest "auto" i po prostu zmieniam go na "default" , czyli to, co auto wybiera przez default.

Możesz użyć dowolnego obiektu zwracanego przez getComputedStyle, którego możesz użyć jako flagi bez zakłócania wyglądu strony, np. border-color.

Chciałbym ustawić własny styl zdefiniowany przez użytkownika w sekcji: active, ale nie mogłem tego uruchomić. Byłoby lepiej, gdyby to było możliwe.

 4
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-27 17:34:36

Krótkie i słodkie

Nie jestem pewien, dlaczego żadna z poprzednich odpowiedzi nie zadziałała dla mnie, ale wpadłem na to rozwiązanie w momencie eureka. Nie tylko działa, ale jest również najbardziej elegancki: {]}

Dodaj do tagu:

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

Następnie przetestuj i wykonaj myfunction() Jeśli down równa się 1:

onmousemove="if (down==1) myfunction();"
 3
Author: Stanley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-02 18:18:29

Możesz połączyć @Pax i moje odpowiedzi, aby również uzyskać czas, przez który mysz została wyłączona:

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);
}

Potem:

if (mousedown >= 2000) {
  // do something if the mousebutton has been down for at least 2 seconds
}
 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-27 00:54:48

Musisz obsłużyć MouseDown i MouseUp i ustawić jakąś flagę lub coś, aby śledzić go "później w dół drogi"... :(

 2
Author: Thomas Hansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-29 22:29:21

Poniżej przykład jQuery, gdy mysz jest ponad $('.element'), kolor zmienia się w zależności od naciśnięcia przycisku myszy.

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
Author: Marcin Żurek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-25 05:05:13

Jak powiedział @Jack, kiedy mouseup dzieje się poza oknem przeglądarki, nie jesteśmy tego świadomi...

Ten kod (prawie) zadziałał dla mnie:

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

Niestety, nie dostanę mouseup zdarzenia w jednym z tych przypadków:

  • użytkownik jednocześnie naciska klawisz klawiatury i przycisk myszy, zwalnia przycisk myszy poza oknem przeglądarki, a następnie zwalnia klawisz.
  • użytkownik naciska dwa przyciski myszy jednocześnie, zwalnia jeden przycisk myszy, a następnie drugi, oba poza oknem przeglądarki.
 0
Author: dreadcast,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 08:14:51

Jeśli pracujesz na złożonej stronie z istniejącymi procesorami obsługi zdarzeń myszy, polecam obsługę tego zdarzenia na capture (zamiast bubble). Aby to zrobić, ustaw trzeci parametr addEventListener na true.

Dodatkowo możesz sprawdzić, czy event.which obsługuje rzeczywistą interakcję z użytkownikiem, a nie zdarzenia myszy, np. 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);

Dodaj obsługę do dokumentu (lub okna) zamiast dokumentu.ciało jest ważne b / C zapewnia, że mouseup wydarzenia poza oknem {[13] } są nadal rejestrowane.

 0
Author: Micah Miller-Eshleman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 19:09:21

Cóż, nie możesz sprawdzić, czy jest w dół po wydarzeniu, ale możesz sprawdzić, czy jest w górę... Jeśli jest na górze.. to znaczy, że już nie jest na dole: p lol

Więc użytkownik naciska przycisk w dół (w zdarzeniu MouseDown)... a potem sprawdzasz, czy jest up (onMouseUp). Dopóki nie jest, możesz robić, co potrzebujesz.

 -1
Author: rogeriopvl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-26 22:37:31
        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;
        }

Ta wersja cross-browser działa dobrze dla mnie.

 -1
Author: user2550945,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-04 14:49:49

Używając jQuery, poniższe rozwiązanie obsługuje nawet "przeciągnij stronę, a następnie zwolnij przypadek".

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

Nie wiem jak radzi sobie z wieloma przyciskami myszy. Gdyby istniał sposób na rozpoczęcie klikania poza oknem, a następnie wprowadzenie myszy do okna, to prawdopodobnie tam też nie działałoby to poprawnie.

 -1
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-04 20:12:41