2009-06-29 6 views
3

Die Szene: Ich schreibe ein integrierbares Widget. Es hat die Form eines <script> Tags, das einen iframe erstellt, der alles enthält, was er anzeigen muss. Der Iframe hat keine src, und das Skript schreibt mit theIframe.contentWindow.document.write() zu ihm. Dadurch bleibt das Widget enthalten, und Element-IDs und -Skripte stehen nicht in Konflikt mit der Seite, auf der das Widget eingebettet ist.Wie baue ich einen iframe mit der gleichen Domain wie die Seite in Safari/WebKit

Der Trick: Das Widget muss in der Lage sein, seine Größe zu ändern. Um dies zu tun, setzt es seinen enthaltenden iframe style.height. Dies erfordert Zugriff auf das DOM der äußeren Seite. In Firefox und IE ist dies zulässig, da das Dokument des iframes und das äußere Dokument einen Ursprung teilen.

Der Twist: In Safari jedoch sind die beiden Dokumente nicht als einen Ursprung zu teilen. Das innere Dokument wird als about:blank angesehen, während das äußere Dokument eindeutig ein anderes Protokoll und eine "Domäne" verwendet (wenn blank als Domäne betrachtet werden kann).

Die Frage: Wie kann ich ein iframe programmatisch erstellen, dessen Dokument Safari/WebKit den gleichen Ursprung wie das Dokument des Fensters, das es erstellt, haben wird?


bearbeiten: Nach weiterem Experimentieren, kann ich nicht einen Weg finden, programmatisch einen Iframe zu erstellen, deren Standort nicht about:blank unabhängig davon, ob ich seinen Inhalt ändern.

Wenn ich den Rahmen mit document.createElement() erstellen, gibt ihm ein src, die auf dem gleichen Ursprung zu einer echten HTML-Ressource Punkte genannt „foo.html“, und document.body.appendChild() es, Safari-Konsole zeigt das Element, wie in dem DOM erwartet, aber Der Inhalt der Seite wird nicht angezeigt, und das Dokument wird in der Seitenleiste als "about: blank" aufgeführt.

Wenn ich den HTML-Code für den iframe direkt auf der Seite einfüge, wird der Inhalt von foo.html angezeigt und "foo.html" wird in der Seitenleiste angezeigt.

Wenn ich den HTML-Code mit document.write() einfügen, bekomme ich das gleiche Ergebnis wie mit document.body.appendChild().

Beide Programmversionen funktionieren in Firefox.

Antwort

0

Aha. Dies scheint ein Fehler in WebKit zu sein. Wenn ein Iframe programmgesteuert erstellt wird, wird das Attribut src ignoriert. Stattdessen wird der Frame standardmäßig auf about:blank gesetzt und muss an eine URL weitergeleitet werden, die auf eine andere Stelle verweist.Zum Beispiel:

theIframe.contentWindow.location = theIframe.src 
+0

Ich brauche ein wenig Klärung. Wo müsste dieses Javascript im Elternfenster oder im iframe selbst ausgeführt werden? Was ist dasIframeContentWindow? Wenn Sie sich auf das Fensterobjekt des Iframes beziehen, wäre das nicht einfach "theIframe"? Das heißt, Sie könnten das auf "theIframe.location = theIframe.src" vereinfachen? Jede Hilfe wäre willkommen, da ich genau auf diesen Fehler gestoßen bin. Vielen Dank. –

+0

Sorry, mir fehlte ein Punkt. theIframe hier ist das iframe-Element, nicht der Rahmen oder das Fenster, das es enthält. theIframe.contentWindow ist das Fensterobjekt, das die innere Seite enthält. Dieser Code wird auf der äußeren Seite ausgeführt, unmittelbar nachdem der Iframe dem DOM hinzugefügt wurde. Dies ist der Punkt, an dem das ContentWindow zuerst existiert (glaube ich). Dies ist auch der Punkt, an dem andere Browser genau dies tun: Navigieren Sie im Fenster des iframe zum iframe src. – Peeja

1

Der beste Vorschlag, den ich geben könnte, ist, den Iframe auf eine leere Seite auf dem gleichen Server (dh blank.html) zu setzen und dann den Inhalt zu bearbeiten. Ein Schmerz in der Rückseite, ich weiß, aber es ist ein Workaround.

könnten Sie auch

iframe.contentDocument.open("replace"); 
iframe.contentDocument.write("<b>This is some content</b>"); 
iframe.contentDocument.close(); 

jedoch versuchen, ich, ob das funktioniert nur im Internet Explorer nicht sicher bin. Entschuldigung, ich könnte nicht hilfreicher sein als das.

+0

Gute Gedanken. Das Problem scheint jedoch tückischer zu sein, als ich dachte. Siehe die Additionen in der Frage. – Peeja