Übergeben Sie Mausereignisse durch ein absolut positioniertes Element

307

Ich versuche, Mausereignisse auf einem Element mit einem anderen absolut positionierten Element darüber zu erfassen.

Im Moment treffen Ereignisse auf dem absolut positionierten Element es und sprudeln zu seinem übergeordneten Element, aber ich möchte, dass es für diese Mausereignisse "transparent" ist und sie an das weiterleitet, was sich dahinter befindet. Wie soll ich das umsetzen?

s4y
quelle

Antworten:

488
pointer-events: none;

Ist eine CSS-Eigenschaft, mit der Ereignisse das Element "durchlaufen", auf das sie angewendet werden, und das Ereignis für das Element "unten" auftritt.

Weitere Informationen finden Sie unter: https://developer.mozilla.org/en/css/pointer-events

Es wird bis IE 11 nicht unterstützt. Alle anderen Anbieter unterstützen es seit geraumer Zeit (der weltweite Support betrug 12/16 ~ 92%): http://caniuse.com/#feat=pointer-events (danke an @ s4y für die Bereitstellung des Links in den Kommentaren) .

JanD
quelle
3
Vielen Dank! Dies ist eine perfekte Lösung für moderne (und Nicht-IE-) Browser. Zum Zeitpunkt der Veröffentlichung dieser Frage glaube ich nicht, dass es sie pointer-eventsgab! Ich kann die akzeptierte Antwort irgendwann auf diese umstellen.
s4y
16
Woah, das hat mir nur Stunden gespart.
Dan Abramov
2
Ich habe gerade die akzeptierte Antwort auf diese umgestellt. Die Unterstützung für pointer-events Still ist nicht besonders gut , aber es wird besser. Eine kompatiblere Option finden Sie in der Antwort von @ JedSchmidt.
s4y
1
Danke, ich wusste nie, dass das tatsächlich existiert. es hat mir Stunden gespart
Mohammed A. Al Jama
2
Was aber, wenn Sie nur ein Ereignis wie das Bildlaufereignis durchlaufen lassen möchten, das oberste Element jedoch weiterhin auf alle anderen Ereignisse reagiert? Wenn Sie Zeigerereignisse auf "Keine" setzen, werden alle Ereignisse im obersten Element beendet.
AndroidDev
50

Wenn Sie nur die Maus herunterfahren müssen, können Sie möglicherweise mit der document.elementFromPointMethode auskommen , indem Sie:

  1. Entfernen der obersten Schicht beim Mousedown,
  2. Übergeben der xund y-Koordinaten vom Ereignis an die document.elementFromPointMethode, um das Element darunter abzurufen, und dann
  3. Wiederherstellen der obersten Schicht.
Jed Schmidt
quelle
9
Weitere wortreiche Erklärung hier: vinylfox.com/forwarding-mouse-events-through-layers
Nathan
2
Genial, ich wusste nicht, dass es diese Methode überhaupt gibt! Es kann auch ganz einfach verwendet werden, um alle Elemente mit einer while- Schleife unter den Cursor zu bringen, um das oberste Element zu erhalten und es dann auszublenden, um das nächste zu finden. Holen
Sie sich
2
Das Problem bei dieser Problemumgehung ist, dass das Zoomen der Seite nicht funktioniert. Für mobile Geräte oder Desktop-Browser bedeutet das Zoomen von XY-Koordinaten nichts mehr und es gibt keine eindeutige Möglichkeit, den Zoom zu berechnen. Ich glaube, für Prise Zoom ist es eigentlich unmöglich.
Impossibear
39

Auch schön zu wissen ...
Zeigerereignisse können für ein übergeordnetes Element (wahrscheinlich transparentes div) deaktiviert und dennoch für untergeordnete Elemente aktiviert werden. Dies ist hilfreich, wenn Sie mit mehreren überlappenden Div-Ebenen arbeiten und auf die untergeordneten Elemente einer Ebene klicken möchten. Dafür erhalten alle Eltern-Divs pointer-events: noneund Click-Children Zeiger-Ereignisse, die von wieder aktiviert werdenpointer-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>
Alles ist eins
quelle
5
Genial, gleich nach dem Höhepunkt der Entdeckung pointer-events:noneund der bevorstehenden Enttäuschung, dass Kinderknoten betroffen sind, retten Sie den Tag :)
Juan Cortés
;) sehr froh darüber
Allisone
Kann man es auf das Wesentliche reduzieren: .parent * { pointer-events:all; }für Kinder?
Dmitry
Es sollte "Zeigerereignisse: auto;" sein. Der Wert "all" gilt nur für SVGs. Siehe developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
mattavatar
7

Der Grund, warum Sie das Ereignis nicht erhalten, ist, dass das absolut positionierte Element kein untergeordnetes Element des Elements ist, auf das Sie "klicken" möchten (blaues Div). Der sauberste Weg, den ich mir vorstellen kann, besteht darin, das absolute Element als Kind desjenigen anzugeben, auf das Sie klicken möchten, aber ich gehe davon aus, dass Sie das nicht können, oder Sie hätten diese Frage hier nicht gestellt :)

Eine andere Möglichkeit wäre, einen Klickereignishandler für das absolute Element zu registrieren und den Klickhandler für das blaue Div aufzurufen, wodurch beide blinken.

Aufgrund der Art und Weise, wie Ereignisse durch das DOM sprudeln, bin ich mir nicht sicher, ob es eine einfachere Antwort für Sie gibt, aber ich bin sehr neugierig, ob jemand andere Tricks hat, von denen ich nichts weiß!

Loktar
quelle
Danke für die Antwort, Loktar. Leider werde ich auf der realen Seite nicht wissen, was sich unter dem absolut positionierten Element befindet, und es kann mehr als ein mögliches Ziel geben. Die einzige Problemumgehung, die ich mir vorstellen kann, besteht darin, die Mauskoordinaten zu erfassen und sie mit möglichen Zielen zu vergleichen, um festzustellen, ob sie sich überschneiden. Das wäre einfach nur böse.
s4y
4

Es ist eine Javascript-Version verfügbar, die Ereignisse manuell von einem Div zu einem anderen umleitet.

Ich habe es aufgeräumt und daraus ein jQuery-Plugin gemacht.

Hier ist das Github-Repository: https://github.com/BaronVonSmeaton/jquery.forwardevents

Leider hat der Zweck, für den ich es verwendet habe - das Überlagern einer Maske über Google Maps - keine Klick- und Ziehereignisse erfasst, und der Mauszeiger ändert sich nicht, was die Benutzererfahrung so stark beeinträchtigt, dass ich mich gerade entschlossen habe, die Maske unter IE und Opera auszublenden. Die beiden Browser, die keine Zeigerereignisse unterstützen.

Mikepote
quelle
1

Wenn Sie die Elemente kennen, für die Mausereignisse erforderlich sind, und wenn Ihre Überlagerung transparent ist, können Sie den Z-Index einfach auf einen höheren Wert als die Überlagerung festlegen. Alle Ereignisse sollten in diesem Fall natürlich in allen Browsern funktionieren.

Ricosrealm
quelle