Wie können Sie einen Iframe mit Zeigerereignissen versehen: keine; aber nicht auf einem div darin?

Lesezeit: 7 Minuten

Benutzer-Avatar
Marc Güselin

Ich habe ein Iframe mit einem geerbten pointer-events: none; aber wenn ich eine eingefügt habe <div> innerhalb des iframe mit a pointer-events: auto; Das div reagiert nicht auf Klicks oder Mausbewegungen.

Der Grund dafür ist, dass die iframe ist drinnen a <div style="position:fixed;">
Es ist also eine Art kleines Menü. Ich möchte aber, dass sich der Benutzer durchklickt iframeaber nicht über die Links und Divs im Iframe.

Und ja, es muss unbedingt ein Iframe bleiben.

Wie könnte ich das umgehen? Kann ich das überhaupt umgehen?

Hier ist ein einfaches Beispiel: jsfiddle.net/MarcGuiselin/yLo119sw/2

  • Könnten Sie eine Demo auf erstellen jsfiddle.net das zeigt das Problem?

    – N3dst4

    6. Januar 2016 um 10:48 Uhr

  • Bitte schön: jsfiddle.net/MarcGuiselin/yLo119sw/1 verzeihen Sie meinen schwachen Versuch des Humors

    – Marc Guiselin

    6. Januar 2016 um 22:01 Uhr

  • Hallo @marc-guiselin, ich habe genau das gleiche Problem. Ich versuche, einen Weg zu finden, aber kein Glück. Ich würde es schätzen, wenn Sie mir Ihre Problemumgehung mitteilen könnten, falls Sie welche gefunden haben … Danke.

    – Hosjay

    21. November 2017 um 1:04 Uhr

  • @hosjay leider habe ich keine gefunden

    – Marc Guiselin

    3. Dezember 2017 um 4:54 Uhr

Benutzer-Avatar
Kamae

Sie arbeiten mit position:absolutegemäß dem Beispiel, das Sie auf jsfiddle hochgeladen haben … Hinzufügen von a z-index auf die Schaltfläche “Sie können nicht auf mich klicken, weil ich mich hinter dem Iframe befinde” ermöglicht es mir, darauf zu klicken.

Z-Index

EDIT: Wenn Sie a pointer-events: none; überall außer in einem divkönnen Sie hinzufügen pointer-events in jedem element anstelle von iframe. Wenn Sie gemäß Ihrem Beispiel in der Geige den Nicholas Cage speichern, aber die anderen Ereignisse blockieren möchten, können Sie Folgendes tun:

switchbutton.onclick=function(){
   this.innerHTML="reload to reset";
   //iframe.style.pointerEvents="none";
   cantclick.innerHTML="You can click me now! :)";
   iframe.contentDocument.body.innerHTML="<button>You can't click me now because my parent iframe is click-through! :(</button><br>or save this gorgeous image of your favorite actor which may or may not be relavant to the problem.<br><img id='nicholasCage' src="http://media2.popsugar-assets.com/files/2014/01/06/008/n/1922283/131b4126c7b8738f_thumb_temp_image333458751389045360.jpg.xxxlarge/i/Best-Nicolas-Cage-Memes.jpg"/>";

   var iframeBody = iframe.contentDocument,
       elements = iframeBody.querySelectorAll("*"),
       i,
       len = elements.length;

   for(i=0;i<len;i++){
       elements[i].style.pointerEvents="none";
   }

   iframeBody.getElementById("nicholasCage").style.pointerEvents="all";
}

Wenn Sie jQuery verwenden können, können Sie dies schneller tun, indem Sie einfach verwenden $("iframe *").css("pointer-events","none");

  • offensichtlich. Das Ziel ist nicht, auf die Schaltfläche über dem Iframe zu klicken, sondern herauszufinden, wie Mousevents durch den Iframe eindringen können, wenn sich das Mousevent nicht auf etwas innerhalb des Iframes befindet

    – Marc Guiselin

    15. Juli 2016 um 11:30 Uhr

  • Entschuldigung, ich glaube, ich verstehe es nicht (mein Fehler, weil mein Englisch ein bisschen scheiße ist …). Ok, jetzt habe ich Ihr jsfiddle gründlich überprüft, wenn NCage erscheint, möchten Sie auf die Schaltfläche “Sie können nicht auf mich klicken …” klicken? Sie können es mit Javascript tun, fragen Sie danach? (Entschuldigung nochmal)

    – Kamae

    15. Juli 2016 um 11:53 Uhr

  • OK, Sie möchten also alle Dinge im Iframe deaktivieren, mit Ausnahme (als Beispiel) das Bild von NCage. Können Sie jQuery oder nur Javascript verwenden?

    – Kamae

    15. Juli 2016 um 12:06 Uhr

  • Nein, das ist eine CSS/HTML-Sache. Zum Beispiel, wenn ich wollte, dass eine Chrome-Erweiterung ein Menü in jede Seite einfügt, die sich in einem Iframe befindet (damit die Website, auf der sie sich befindet, nicht durcheinander gebracht wird) und dieses Menü die gesamte Seite abdeckt. Wenn ich in die Mitte des Iframes klicken würde (wo kein Menü ist), würde ich immer noch auf den Iframe klicken und nicht auf das Zeug dahinter. Sie können dies nicht effizient mit Javascript tun. Es wäre ungeheuer komplex und würde auf den meisten Websites nicht funktionieren. Aber wenn Sie den Iframe irgendwie zum Durchklicken bringen könnten, könnten Sie all diese Probleme beheben. das ist was ich suche.

    – Marc Guiselin

    15. Juli 2016 um 12:55 Uhr

  • Aaah OK sorry, das habe ich nicht verstanden! Nun, in diesem Fall weiß ich nicht, ob Sie es nur mit CSS machen können … Ich habe es mit JS bekommen. In diesem Beispiel können Sie beide anklicken, aber es ist ein bisschen knifflig… jsfiddle.net/Kamae/e51zykkh Es macht nur den iframe “z-index -1”, ruft die Mausposition ab, löst einen Klick aus und macht den iframe wieder “z-index 0” … Das ist alles, was ich tun kann, tut mir leid, wenn Ihnen das nicht hilft überhaupt. Viel Glück!

    – Kamae

    15. Juli 2016 um 13:55 Uhr

Benutzer-Avatar
Troja

Ich habe viel recherchiert und selbst einen Workaround gefunden.

    // the iframe element
    const frame = document.getElementsByTagName("iframe")[0];
    frame.onload = function () {
      const frameDocument = frame.contentDocument;
      document.addEventListener("mousemove", onMouseMove, true);
      frameDocument.addEventListener("mousemove", onMouseMove, true);

      function onMouseMove(e) {
        let coord;
        if (e.currentTarget === document) {
          coord = {
            x: e.pageX - frame.offsetLeft,
            y: e.pageY - frame.offsetTop,
          };
        } else {
          coord = { x: e.clientX, y: e.clientY };
        }

        const el = frameDocument.elementFromPoint(coord.x, coord.y);
        // you can compare to your own element if needed
        frame.style.pointerEvents = !el || el === frameDocument.body ? "none" : "auto";
      }
    };

Der Iframe schaltet automatisch um pointer-events und alle Ereignisse funktionieren einfach nahtlos.

Was wir wollen, erlaubt die Spezifikation nicht, zumindest nicht mit einem absolut positionierter iframe.

Wir wollen alle dasselbe tun:

  • Rendern Sie einen Container (normalerweise für eine Chrome-Erweiterung), der über der Seite positioniert ist und den Darstellungsbereich ausfüllt
  • Container nicht zulassen selbst von der Erfassung von Zeigerereignissen
  • Lassen Sie die Container Kinder Zeigerereignisse zu erfassen

Dadurch können wir durch die absolut positionierte Box “klicken”, aber dennoch mit ihren Kindern interagieren, die Schaltflächen oder nur Boxen mit Hover-Ereignissen oder was auch immer sein können.

Wir können dieses Verhalten nur dann erreichen, wenn die Boxen dasselbe Dokument verwenden. Deaktivieren von Zeigerereignissen für eine absolut positionierte iframe deaktiviert sie für alle seine Kinder.

Ein alternativer Ansatz ist das Rendern des Inhalts direkt in das Dokument, dh in ein Shadow-DOM für das Sandboxing von Stilen. Dies ist die einzige Möglichkeit, dieses Verhalten zu erreichen, da wir danach suchen, und so habe ich das Problem zuvor angegangen, bevor ich versucht habe, ein iframe umzugestalten, und festgestellt habe, dass es auf diese Weise nicht repliziert werden kann.

Sehen https://iframe-pointer-events.vercel.app für eine Demo.

Sie können dies auf keinen Fall tun, da dies neben Clickjacking ein weiteres Sicherheitsproblem darstellen würde.

Stile innerhalb von Iframe kooperieren in keiner Weise mit Stilen innerhalb der Host-Site. Wenn Sie also sogar z-index/pointer-events oder etwas anderes auf iframe setzen und versuchen würden, die darin enthaltene Regel zu überschreiben, gilt dies in keiner Weise für Host-Site-Regeln.

Also, was ist die Lösung? Sie müssen Ihren Iframe in mehrere aufteilen und an deren Position basteln.

Geben Sie nicht den ganzen Iframe an pointer-events: none. Nur innerhalb der iframe Setzen Sie eine CSS-Regel body * { pointer-events: none;}

Auf diese Weise blockiert der Iframe keine Ereignisse, Elemente innerhalb des Iframes sind jedoch nicht anklickbar.

  • Das Ziel besteht darin, herauszufinden, wie man Klicks erlauben kann, durch den Iframe zu dringen, wenn der Klick nicht auf etwas innerhalb des Iframes erfolgt. Sie möchten in der Lage sein, auf Dinge innerhalb des Iframes zu klicken, sonst ruiniert das den Zweck.

    – Marc Guiselin

    24. September 2016 um 15:40 Uhr

Benutzer-Avatar
wingit86

Hast du das versucht?

pointer-events: inherit;

Ich weiß, dass du deine Antwort bereits bekommen hast, aber ich dachte, das könnte auch funktionieren.

  • Das Ziel besteht darin, herauszufinden, wie man Klicks erlauben kann, durch den Iframe zu dringen, wenn der Klick nicht auf etwas innerhalb des Iframes erfolgt. Sie möchten in der Lage sein, auf Dinge innerhalb des Iframes zu klicken, sonst ruiniert das den Zweck.

    – Marc Guiselin

    24. September 2016 um 15:40 Uhr

1116390cookie-checkWie können Sie einen Iframe mit Zeigerereignissen versehen: keine; aber nicht auf einem div darin?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy