Wie kann man eine Lightbox in einem iframe öffnen ohne Begrenzung des iframe?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Du kannst den iFrame mittels des CSS-Properties overflow scrollbar machen, sofern er das nicht schon ist. Wobei ich den Wert wohl auf auto halten würde. Wenn das eingebettete Dokument (bzw. die Lightbox) eine entsprechende Größe anfordert, sollte der Browser selbst auf die Idee kommen, Scrollleisten zu ergänzen.

Aus dem iFrame-Rahmen kommst du aber soweit nicht heraus.

Du könntest stattdessen via JavaScript auf das Elternfenster zugreifen und so das DOM manipulieren.

window.parent.document.getElementById("some-element").textContent = "Hello world!";

Das heißt, die Lightbox sollte eher auf der Elternseite eingebunden werden und der iFrame triggert die Anzeige aus seinem Bereich heraus.

Die wohl beste Lösung wäre es allerdings, auf einen iFrame zu verzichten und stattdessen den relevanten Inhalt bspw. via PHP zu inkludieren.

Beispiel:

<!doctype html>
<title>Main page</title>
<body>
  <!-- some content ... -->
  <?php include "subpage.html" ?>
  <!-- further content ... -->
</body>

Für die Ausführung von PHP brauchst du einen Webserver (wie den Apache HTTP Server), der für PHP konfiguriert ist. Die Datei, die inkludiert, braucht die Endung .php.

Damit du kein falsches HTML zusammenbaust, sollten in subpage.html zudem nur die Inhaltselemente stehen, kein Doctype, head-Bereich oder body-Tag. Verweise auf CSS müssen direkt in der einbettetenden Seite eingefügt werden.

Wenn die Subseite noch einmal woanders als eigenständige Seite vorhanden sein soll, könnte man die subpage.html erneut in ein anderes Dokument inkludieren.

Transposon 
Fragesteller
 09.06.2022, 16:44

Vielen Dank für deine sehr hilfreiche Antwort. Da es ein Wordpress-Plugin ist, werde ich wohl die Lightbox nicht ohne weiteres verlagern können und muss das Karussell wohl komplett selbst schreiben?

Ein Beispiel habe ich hier mal erstellt, wie das iframe lädt und im grauen Bereich darunter, wie es am Ende aussehen soll.

http://wp13747543.server-he.de/videoleiste/

0
regex9  09.06.2022, 19:13
@Transposon

Der Slider darf einfach nicht via iFrame eingebunden werden sondern muss direkt auf die Seite, so wie du es in deinem grauen Bereich auch hast.

Nun weiß ich nicht, woran es scheitert, die Lösung aus dem grauen Bereich bereits jetzt zu verwenden. So oder so ist eine komplette Eigenentwicklung eines Karussels aber keinesfalls notwendig. Zum einen gibt es ganz sicher noch andere WordPress-Plugins für Lightbox-Carousels und zum anderen kann man auf Lösungen wie Owl Carousel oder slick zurückgreifen. Letztere müssten lediglich noch so angepasst werden, sodass die in WordPress ausgewählten Bilder eingesetzt werden. Das heißt, ein paar technische Kenntnisse zu HTML, PHP, JavaScript und WordPress-Templates wären notwendig.

1
Transposon 
Fragesteller
 10.06.2022, 00:44
@regex9

Grundkenntnisse und etwas (leicht) fortgeschrittene Kenntnisse in html, php, javascript und css sind vorhanden. Es geht einfach nur ums Nachladen lassen. Deshalb möchte ich Videoleisten mit bis zu 80 Videos pro Leiste (und davon jeweils 5-8 untereinander) nachladen lassen, weil der Seitenaufbau sonst zu lange braucht. Meine Versuche mit Ajax und Fetch sind gescheitert, weil man hiermit keinen html, js und css content auf einmal laden lassen kann, deshalb dachte ich eine Lösung wären iframes - dann könnte ich eine Videoleiste pro Seite packen und auf einer Seite jeweils nachladen lassen. Das klappt ja soweit auch gut, nur dass die Lightbox eben auch über den Rand hinaus schauen muss. Hierzu fand ich im Netz: ",,If both sites belong to the same domain you can add the JS of the lightbox to the main frame and call the function inside the iframe using ´parent.function". Bei der Umsetzung bin ich aber noch am Rätselraten - dank dir aber schon einen Erkenntnisschritt weiter - wofür ich dir sehr doll danke.

0
regex9  10.06.2022, 04:59
@Transposon
Es geht einfach nur ums Nachladen lassen.

Die einzigen Elemente, die direkt geladen werden, sind die Bilder. Die Videoelemente werden, soweit ich das sehe, erst beim Öffnen der Lightbox generiert.

Mit iFrames erleichterst du das Laden nicht wirklich. Für das Laden aller Ressourcen stehen dem Browser in der Regel eine bestimmte Anzahl an Threads zur Verfügung (zwischen 2-8), die die Seite laden. Wenn alle blockiert sind, werden anschließende Ressourcen aufgeschoben, was den Ladevorgang der Seite verlängert. Das Laden eines iFrames blockiert mindestens einen Thread.

Ein Lazy Loading-Ansatz wäre die bessere Lösung. Das aktuelle Verhalten (Video wird erst beim Öffnen der Lightbox erstellt und geladen) entspricht bereits einem solchen Weg. Ebenso könntest du die Slider nach und nach (z.B. beim Scrollen oder nach Klick auf einen Load-More-Button) laden lassen.

Meine Versuche mit Ajax und Fetch sind gescheitert, weil man hiermit keinen html, js und css content auf einmal laden lassen kann

Bei einem Lazy Loading würde es ausreichen, vom Server nach und nach HTML nachgereicht zu bekommen, welches dann ins DOM eingesetzt wird. Im Anschluss müssten die Elemente an die JavaScript-Listeners der Lightbox-Bibliothek gebunden werden. Wie es sich bei deinem Slider verhält, müsstest du selbst einmal nachschauen. Bei einer klassischen jQuery-Fancybox-Bibliothek würde es ungefähr so aussehen:

fetch("/loadmorehandler")
  .then(response => response.text())
  .then(html => {
    $(".container").append(html);
    $(".container .video-teaser").fancybox({ /* some options ... */ });
  });

Erst wird also das HTML geholt, welches nachgeladen werden soll und in den entsprechenden Container gehängt. Der Einfachheit halber kann das ruhig eine neue Box sein, die noch leer ist. So können alte Elemente von neuen Elementen leicht getrennt werden, zumal man ja eh nur die neuen Elemente im nächsten Schritt noch binden möchte.

Im letzten Schritt erfolgt die Bindung. Wie das bei deinem Slider konkret gemacht wird, müsstest du wie gesagt einmal nachschauen.

",,If both sites belong to the same domain you can add the JS of the lightbox to the main frame and call the function inside the iframe using ´parent.function".

Das ist genau das, was ich oben auch schrieb:

Du könntest stattdessen via JavaScript auf das Elternfenster zugreifen und so das DOM manipulieren.

Auf der Seite selbst (die den iFrame einbindet) wird der JavaScript-Code eingebunden, der die Lightbox öffnet (bspw. in Form einer Funktion). Im iFrame bekommen die einzelnen Teaser im Slider einen Handler für das Klickereignis zugewiesen. In dem greifst du auf die Funktion aus der Elternseite zu.

Funktion in Elternseite:

function openLightbox(videoUrl) {
  /* ... */
}

Handler für das Klickereignis:

const teasers = document.querySelectorAll(".video-teaser");

for (const teaser of teasers) {
  teaser.addEventListener("click", () => {
    const videoUrl = teaser.getAttribute("data-video-url");
    window.parent.openLightbox(videoUrl);
  });
}

Bei diesem angedeuteten Beispiel würde ich davon ausgehen, dass jeder Teaser im Slider ein data-Attribut besitzt, in dem die Video-URL steht.

<div class="slider">
  <div class="video-teaser" data-video-url="URL to some video ..."><!-- ... --></div>
  <div class="video-teaser" data-video-url="URL to some other video ..."><!-- ... --></div>
  <!-- etc. -->
</div>
0
regex9  10.06.2022, 05:39
@regex9

Diesen zuletzt beschriebenen Weg würde ich allerdings (wie schon geschrieben) vermeiden. Gänzlich auf iFrames zu verzichten, ist die bessere Lösung.

1
Transposon 
Fragesteller
 11.06.2022, 02:36
@regex9

Ich danke dir nochmal vielmals für deine äußerst detaillierte Anleitung. Werde mich in den kommenden Wochen ransetzen und beide Methoden mal ausprobieren. DANKE!

0