350 votes

Faire passer les événements de la souris par un élément absolument positionné

J'essaie de capturer les événements de souris sur un élément sur lequel se trouve un autre élément absolument positionné.

Pour l'instant, les événements sur l'élément positionné de manière absolue le touchent et remontent jusqu'à son parent, mais je veux qu'il soit "transparent" à ces événements de souris et les transmette à ce qui se trouve derrière lui. Comment dois-je m'y prendre ?

561voto

JanD Points 1532
pointer-events: none;

Est une propriété CSS qui fait en sorte que les événements "passent par" l'élément HTML auquel la propriété est appliquée. L'événement se produit sur l'élément "inférieur".

Voir pour les détails : https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

Il est pris en charge par presque tous les navigateurs, y compris IE11 ; la prise en charge globale était de ~98,2% en 05/'21) : http://caniuse.com/#feat=pointer-events (merci à @s4y d'avoir fourni le lien dans les commentaires).

3 votes

Merci ! C'est une solution parfaite pour les navigateurs modernes (et non IE). Au moment où cette question a été postée, je ne pense pas que pointer-events existé ! Il se peut que je remplace la réponse acceptée par celle-ci à un moment donné.

22 votes

Woah, ça vient de me faire gagner des heures.

2 votes

Je viens de remplacer la réponse acceptée par celle-ci. Support pour pointer-events n'est toujours pas super génial mais ça s'améliore. Pour une option plus compatible, allez avec la réponse de @JedSchmidt.

50voto

Jed Schmidt Points 2055

Si vous n'avez besoin que de la souris, vous pouvez vous contenter de l'option document.elementFromPoint méthode, par :

  1. en enlevant la couche supérieure sur le mousedown,
  2. en passant le x y y les coordonnées de l'événement à l document.elementFromPoint pour obtenir l'élément situé en dessous, puis
  3. en restaurant la couche supérieure.

9 votes

Une explication plus détaillée ici : vinylfox.com/forwarding-mouse-events-through-layers

2 votes

Génial, je ne savais pas que cette méthode existait ! On peut aussi l'utiliser assez facilement pour obtenir tous les éléments sous le curseur en utilisant une fonction tandis que boucle pour obtenir l'élément le plus haut et le cacher afin de trouver l'élément suivant. Téléchargez ma version ici : gist.github.com/Pichan/5498404

2 votes

Le problème de cette solution de contournement est qu'elle ne fonctionne pas avec le zoom de la page. Pour les appareils mobiles ou les navigateurs de bureau, les coordonnées X et Y du zoom ne signifient plus rien, et il n'y a pas de moyen clair de calculer le zoom. Je crois que pour le pinch zooming, c'est en fait impossible.

9voto

Loktar Points 261

La raison pour laquelle vous ne recevez pas l'événement est que l'élément positionné de manière absolue n'est pas un enfant de l'élément que vous voulez "cliquer" (div bleu). Le moyen le plus propre auquel je pense est de placer l'élément absolu comme enfant de l'élément sur lequel vous voulez cliquer, mais je suppose que vous ne pouvez pas faire cela, sinon vous n'auriez pas posté cette question ici :)

Une autre possibilité serait d'enregistrer un gestionnaire d'événement de clic pour l'élément absolu et d'appeler le gestionnaire de clic pour la division bleue, ce qui les ferait clignoter toutes les deux.

En raison de la façon dont les événements remontent dans le DOM, je ne suis pas sûr qu'il existe une réponse plus simple pour vous, mais je suis très curieux de savoir si quelqu'un d'autre a des astuces que je ne connais pas !

0 votes

Merci pour la réponse, Loktar. Malheureusement, sur la page réelle, je ne vais pas savoir ce qui se trouve sous l'élément positionné de manière absolue, et il peut y avoir plus d'une cible possible. La seule solution à laquelle je pense est de saisir les coordonnées de la souris et de les comparer aux cibles possibles pour voir si elles se croisent. Ce serait tout simplement désagréable.

4voto

Mikepote Points 798

Il existe une version javascript qui redirige manuellement les événements d'une division à une autre.

Je l'ai nettoyé et transformé en un plugin jQuery.

Voici le dépôt Github : https://github.com/BaronVonSmeaton/jquery.forwardevents

Malheureusement, l'objectif pour lequel je l'utilisais - superposer un masque sur Google Maps - ne capturait pas les événements de clic et de déplacement, et le curseur de la souris ne changeait pas, ce qui dégradait suffisamment l'expérience utilisateur pour que je décide de masquer le masque sous IE et Opera - les deux navigateurs qui ne supportent pas les événements de pointeur.

1voto

ricosrealm Points 654

Si vous connaissez les éléments qui ont besoin d'événements souris, et si votre superposition est transparente, vous pouvez simplement définir leur z-index à un niveau supérieur à celui de la superposition. Tous les événements devraient bien sûr fonctionner dans ce cas sur tous les navigateurs.

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