110 votes

Comment simuler un survol de souris en JavaScript pur qui active le CSS ":hover" ?

J'ai essayé de trouver du code pour simuler mouseover dans Chrome, mais même si l'écouteur "mouseover" est activé, la déclaration CSS "hover" n'est jamais définie !

J'ai aussi essayé de le faire :

//Called within mouseover listener
theElement.classList.add("hover");

Mais rien ne semble changer l'élément à ce qui est déclaré dans son hover déclaration.

Est-ce possible ?

130voto

Benjamin Gruenbaum Points 51406

Tu ne peux pas. Ce n'est pas un événement de confiance .

Les événements qui sont générés par l'agent utilisateur, soit à la suite d'une interaction avec l'utilisateur, soit à la suite directe de modifications apportées au DOM, font l'objet d'une confiance de la part de l'agent utilisateur avec des privilèges qui ne sont pas accordés aux événements générés par script via la méthode DocumentEvent.createEvent("Event"), modifiés à l'aide de la méthode Event.initEvent() ou distribués via la méthode EventTarget.dispatchEvent(). L'attribut isTrusted des événements fiables a une valeur de true, tandis que les événements non fiables ont une valeur d'attribut isTrusted de false.

Le plus les événements non fiables ne doivent pas déclencher d'actions par défaut à l'exception des événements click ou DOMActivate.

Vous devez ajouter une classe et l'ajouter/supprimer manuellement sur les événements mouseover/mouseout.

77voto

lbpeppers Points 283

Vous pouvez simuler l'événement mouseover comme ceci :

HTML

<div id="name">My Name</div>

JavaScript

var element = document.getElementById('name');
element.addEventListener('mouseover', function() {
  console.log('Event triggered');
});

var event = new MouseEvent('mouseover', {
  'view': window,
  'bubbles': true,
  'cancelable': true
});

element.dispatchEvent(event);

20voto

Amstutz Points 292

Contexte

Je suis tombé sur cette question en essayant d'écrire des tests automatisés, pour vérifier qu'un certain ensemble d'éléments sur une page donnée reçoivent tous les propriétés css définies par le css pour les événements de survol.

Bien que la réponse ci-dessus explique parfaitement pourquoi il n'est pas possible de déclencher simplement l'événement de survol par JS et de sonder ensuite une valeur CSS intéressante, elle ne répond que partiellement à la question initiale "Comment puis-je simuler un survol de souris en JavaScript pur qui active le CSS ":hover" ?

Avis de non-responsabilité

Ce n'est pas une solution performante. Nous l'utilisons uniquement pour les tests automatisés, où les performances ne sont pas un problème.

Solution

simulateCssEvent = function(type){
    var id = 'simulatedStyle';

    var generateEvent = function(selector){
        var style = "";
        for (var i in document.styleSheets) {
            var rules = document.styleSheets[i].cssRules;
            for (var r in rules) {
                if(rules[r].cssText && rules[r].selectorText){
                    if(rules[r].selectorText.indexOf(selector) > -1){
                        var regex = new RegExp(selector,"g")
                        var text = rules[r].cssText.replace(regex,"");
                        style += text+"\n";
                    }
                }
            }
        }
        $("head").append("<style id="+id+">"+style+"</style>");
    };

    var stopEvent = function(){
        $("#"+id).remove();
    };

    switch(type) {
        case "hover":
            return generateEvent(":hover");
        case "stop":
            return stopEvent();
    }
}

Explication

generateEvent lit tous les fichiers css, remplace :hover par une chaîne vide et l'applique. Cela a pour effet d'appliquer tous les styles :hover. On peut maintenant rechercher un style de survol et revenir à l'état initial en arrêtant la simulation.

Pourquoi appliquer l'effet de survol à l'ensemble du document et pas seulement à l'élément concerné en le récupérant dans les feuilles et en effectuant ensuite un element.css(...) ?

Ainsi, le style serait appliqué en ligne, ce qui remplacerait d'autres styles, qui pourraient ne pas être remplacés par le style de survol css original.

Comment puis-je maintenant simuler le survol d'un seul élément ?

Ce n'est pas performant, donc mieux vaut ne pas le faire. Si vous devez le faire, vous pouvez vérifier avec element.is(selectorOfInterest) si le style s'applique à votre élément et n'utiliser que ces styles.

Ejemplo

Dans Jasmine, vous pouvez par exemple maintenant exécuter :

describe("Simulate CSS Event", function() {
    it("Simulate Link Hover", function () {
      expect($("a").css("text-decoration")).toBe("none");
      simulateCssEvent('hover');
      expect($("a").css("text-decoration")).toBe("underline");
      simulateCssEvent('stop');
      expect($("a").css("text-decoration")).toBe("none");
    });
});

7voto

Yotam Omer Points 8473

Ce que je fais habituellement dans ce cas, c'est d'ajouter une classe en utilisant le javascript.. et de joindre le même CSS comme le :hover à cette classe

Essayez d'utiliser

theElement.addEventListener('onmouseover', 
    function(){ theElement.className += ' hovered' });

Ou pour les anciens navigateurs :

theElement.onmouseover = function(){theElement.className += ' hovered'};

vous devrez bien sûr utiliser onmouseout pour enlever la classe "hovered" quand on quitte l'élément...

4voto

Vulcan Points 14343

Vous pouvez utiliser pseudo:styler une bibliothèque qui permet d'appliquer des pseudo-classes CSS aux éléments.

(async () => {
  let styler = new PseudoStyler();
  await styler.loadDocumentStyles();
  document.getElementById('button').addEventListener('click', () => {
    const element = document.getElementById('test')
    styler.toggleStyle(element, ':hover');
  })
})();

Avertissement : Je suis coauteur de cette bibliothèque. Nous l'avons conçue pour qu'elle prenne également en charge les feuilles de style d'origine croisée, en particulier pour les extensions Chrome où vous n'avez probablement pas le contrôle des règles CSS de la page.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X