Question

Existe-t-il un moyen de détecter si un bouton de la souris est actuellement enfoncé dans JavaScript?

Je connais le "mousedown". événement, mais ce n'est pas ce dont j'ai besoin. Quelque temps après avoir appuyé sur le bouton de la souris, je veux pouvoir détecter s'il est toujours enfoncé.

Est-ce possible?

Était-ce utile?

La solution

Concernant la solution de Pax: cela ne fonctionne pas si l’utilisateur clique sur plus d’un bouton, intentionnellement ou accidentellement. Ne me demandez pas comment je sais: - (.

Le code correct devrait ressembler à ça:

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

Avec le test comme ceci:

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

Si vous voulez savoir quel bouton est enfoncé, préparez-vous à faire de mouseDown un tableau de compteurs et à les compter séparément pour des boutons distincts:

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

Vous pouvez maintenant vérifier quels boutons ont été enfoncés exactement:

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

Sachez maintenant que le code ci-dessus ne fonctionne que pour les navigateurs conformes aux normes qui vous transmettent un numéro de bouton à partir de 0 et plus. IE utilise un masque de bits des boutons actuellement enfoncés:

  • 0 car "rien n'est activé"
  • 1 pour la gauche
  • 2 pour le droit
  • 4 pour le milieu
  • et toute combinaison de ce qui précède, par exemple 5 pour gauche + milieu

Alors ajustez votre code en conséquence! Je le laisse comme un exercice.

Et souvenez-vous: IE utilise un objet événement global appelé… "événement".

Incidemment, Internet Explorer dispose d’une fonctionnalité utile dans votre cas: lorsque d’autres navigateurs envoient un "bouton". uniquement pour les événements de bouton de la souris (onclick, onmousedown et onmouseup), IE l'envoie également avec onmousemove. Vous pouvez donc commencer à écouter onmousemove lorsque vous devez connaître l'état du bouton et rechercher evt.button dès que vous l'avez obtenu. Vous savez maintenant quels boutons de la souris ont été enfoncés:

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

Bien sûr, vous n’obtenez rien si elle joue morte et ne bouge pas.

Liens pertinents:

Mise à jour n ° 1 : je ne sais pas pourquoi j'ai transféré le code document.body-style. Il sera préférable d’attacher des gestionnaires d’événements directement au document.

Autres conseils

C’est une vieille question et les réponses ici semblent plutôt préconiser l’utilisation de mousedown et de mouseup pour savoir si un bouton est enfoncé. Mais comme d’autres l'ont déjà souligné, mouseup ne se déclenchera que s'il est exécuté dans le navigateur, ce qui peut entraîner une perte de suivi de l'état du bouton.

Cependant, MouseEvent (maintenant) indique les boutons correspondants. actuellement poussé:

  • Pour tous les navigateurs modernes (sauf Safari), utilisez MouseEvent.buttons
  • Pour Safari, utilisez MouseEvent.which (les boutons ne seront pas définis pour Safari). Remarque: utilise des numéros différents des boutons pour les clics droit et moyen.

Lorsqu'il est enregistré sur le document , mousemove se déclenche immédiatement dès que le curseur entre à nouveau dans le navigateur. Ainsi, si l'utilisateur libère des modifications extérieures, l'état sera mis à jour dès que ils reviennent à la souris.

Une implémentation simple pourrait ressembler à:

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;

Si des scénarios plus complexes sont nécessaires (différents boutons / plusieurs boutons / touches de contrôle), consultez la documentation MouseEvent. Quand / si Safari élève son jeu, cela devrait devenir plus facile.

Je pense que la meilleure approche consiste à conserver votre propre enregistrement de l'état du bouton de la souris, comme suit:

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

et plus tard dans votre code:

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

la solution n'est pas bonne. on pourrait " mousedown " sur le document, puis "mouseup". en dehors du navigateur, et dans ce cas, le navigateur pense toujours que la souris est enfoncée.

la seule bonne solution consiste à utiliser l'objet IE.event.

Je sais que c'est un ancien message, mais je pensais que le suivi du bouton de la souris à l'aide de la souris haut / bas était un peu maladroit. J'ai donc trouvé une alternative qui pourrait plaire à certains.

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

Le sélecteur: active gère le clic de la souris beaucoup mieux que la souris haut / bas. Vous avez juste besoin d’un moyen de lire cet état dans l’événement onmousemove. Pour cela, je devais tricher et me basais sur le fait que le curseur par défaut était "auto". et je viens de le changer en "" défaut ", qui est ce que sélectionne automatiquement par défaut.

Vous pouvez utiliser tout objet renvoyé par getComputedStyle que vous pouvez utiliser en tant qu'indicateur sans modifier l'apparence de votre page, par exemple. couleur de bordure.

J'aurais aimé définir mon propre style défini par l'utilisateur dans la section: active, mais je ne pouvais pas le faire fonctionner. Ce serait mieux si c'était possible.

L'extrait de code suivant tente d'exécuter le fichier "& # 160;" 2 secondes après l’événement mouseDown dans document.body. Si l'utilisateur lève le bouton, l'événement mouseUp se produira et annulera l'exécution différée.

Je vous conseillerais d'utiliser une méthode pour l'attachement d'événements inter-navigateurs - le paramétrage explicite des propriétés mousedown et mouseup a été effectué pour simplifier l'exemple.

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

court et doux

Je ne suis pas sûr de savoir pourquoi aucune des réponses précédentes ne fonctionnait pour moi, mais je suis parvenu à cette solution pendant un moment eureka. Cela fonctionne non seulement, mais il est aussi très élégant:

Ajouter à la balise body:

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

Testez et exécutez myfunction () si bas est égal à 1 :

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

Vous pouvez combiner @Pax et mes réponses pour obtenir également la durée pendant laquelle la souris est hors service:

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

Puis plus tard:

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

Vous devez gérer MouseDown et MouseUp et définir un indicateur ou quelque chose pour le suivre "plus tard sur la route" ...: (

Avec jQuery, la solution suivante gère même le "glisser en dehors de la page, puis relâcher la casse".

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

Je ne sais pas comment il gère plusieurs boutons de la souris. S’il existe un moyen de lancer le clic en dehors de la fenêtre et d’amener la souris dans la fenêtre, cela ne fonctionnera probablement pas correctement dans ce cas non plus.

Sous l'exemple jQuery, lorsque la souris est au-dessus de $ ('. élément'), la couleur change en fonction du bouton de la souris sur lequel vous appuyez.

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

Comme l'a dit @Jack, lorsque mouseup apparaît en dehors de la fenêtre du navigateur, nous n'en avons pas conscience ...

Ce code a fonctionné (presque) pour moi:

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

Malheureusement, l'événement mouseup ne se produira pas dans l'un de ces cas:

  • l'utilisateur appuie simultanément sur une touche du clavier et un bouton de la souris, relâche le bouton de la souris en dehors de la fenêtre du navigateur, puis relâche la touche.
  • l'utilisateur appuie simultanément sur deux boutons de la souris, relâche un bouton de la souris puis l'autre, les deux en dehors de la fenêtre du navigateur.

Si vous travaillez dans une page complexe avec des gestionnaires d'événements de souris existants, nous vous recommandons de gérer l'événement sur capture (au lieu de bulle). Pour ce faire, définissez simplement le 3ème paramètre de addEventListener sur true .

De plus, vous pouvez vouloir vérifier event.which pour vous assurer de gérer les interactions utilisateur et non les événements de souris, par exemple. elem.dispatchEvent (nouvel événement ('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);

Ajouter le gestionnaire au document (ou à la fenêtre) au lieu de document.body est important car il garantit que les événements de souris en dehors de la fenêtre sont toujours enregistrés.

Eh bien, vous ne pouvez pas vérifier s’il est en panne après l’événement, mais vous pouvez vérifier si c’est Up ... Si ça marche ... ça veut dire qu’il n’est plus en panne: P lol

L'utilisateur appuie donc sur le bouton (événement onMouseDown) ... et après cela, vous vérifiez si est actif (onMouseUp). Même si ce n’est pas le cas, vous pouvez faire ce dont vous avez besoin.

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

cette version multi-navigateurs fonctionne bien pour moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top