web-dev-qa-db-fra.com

Passer des événements de souris à travers un élément en position absolue

J'essaie de capturer des événements de souris sur un élément avec un autre élément absolument positionné dessus.

À l'heure actuelle, les événements sur l'élément en position absolue le touchent et bouillonnent jusqu'à son parent, mais je veux qu'il soit "transparent" pour ces événements de souris et les transmettre à tout ce qui se trouve derrière. Comment dois-je implémenter cela?

278
s4y
pointer-events: none;

Est une propriété CSS qui fait que les événements "traversent" l'élément auquel il est appliqué et que l'événement se produit sur l'élément "ci-dessous".

Voir pour plus de détails: https://developer.mozilla.org/en/css/pointer-events

Il n'est pas pris en charge jusqu'à IE 11; tous les autres fournisseurs le supportent depuis un certain temps (le support global était d'environ 92% en 12/12): http://caniuse.com/#feat=pointer-events (merci à @ s4y pour fournissant le lien dans les commentaires).

441
JanD

Si tout ce dont vous avez besoin est mousedown, vous pourrez peut-être vous contenter de la méthode document.elementFromPoint , par:

  1. enlever la couche supérieure du mousedown,
  2. transmission des coordonnées x et y de l'événement à la méthode _document.elementFromPoint_ pour obtenir l'élément situé en dessous, puis
  3. restaurer la couche supérieure.
48
Jed Schmidt

Aussi agréable à savoir ...
Les événements de pointeur peuvent être désactivés pour un élément parent (probablement transparent div) et être activés pour les éléments enfants. Ceci est utile si vous travaillez avec plusieurs calques div qui se chevauchent, pour lesquels vous voulez pouvoir cliquer sur les éléments enfants de n'importe quel calque. Pour cela, tous les divs parents reçoivent pointer-events: none et les enfants de clics obtiennent des événements de pointeur réactivés par pointer-events: all

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:all;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>
35
Allisone

La raison pour laquelle vous ne recevez pas l'événement est que l'élément en position absolue n'est pas un enfant de l'élément que vous souhaitez "cliquer" (div en bleu). La façon la plus propre de penser est de mettre l'élément absolu en tant qu'enfant de celui sur lequel vous voulez cliquer, mais je suppose que vous ne pouvez pas faire cela ou vous n'auriez pas posté cette question ici :)

Une autre option serait d’enregistrer un gestionnaire d’événements clic pour l’élément absolu et d’appeler le gestionnaire de clics pour la div bleue, ce qui les ferait flasher.

En raison de la façon dont les événements se déroulent 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!

7
Loktar

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

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

Voici le référentiel Github: https://github.com/BaronVonSmeaton/jquery.forwardevents

Malheureusement, le but pour lequel je l'utilisais - superposer un masque sur Google Maps ne capturait pas les événements de clic et de glisser, 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 prennent pas en charge les événements de pointeur.

3
Mikepote

Si vous connaissez les éléments qui nécessitent des événements de souris et si votre superposition est transparente, vous pouvez simplement définir leur index z à une valeur supérieure à celle de la superposition. Bien entendu, tous les événements devraient fonctionner dans tous les navigateurs.

1
ricosrealm