Wenn Sie zur Zeit der Erstellung dieses Artikels nach diesem Problem googeln, finden Sie einige unvollständige Antworten und andere Snippets, die diese schlechte Praxis befürworten.
<!-- NO! Bad! -->
<iframe src="..." style="visibility:hidden;" onload="this.style.visibility='visible';"></iframe>
Der Grund, warum dies schlecht ist, ist, dass der CSS den iframe egal was passiert ausblendet und Benutzer mit deaktiviertem JavaScript diesen iframe niemals sehen werden. Nun, ich bin normalerweise nicht jemand, der extreme Anstrengungen unternimmt, um dieser Menge entgegenzukommen, aber ich bin jederzeit für bessere Lösungen, die dieses Problem lösen, wenn sie verfügbar sind.
Die Lösung
Dank Paul Irish und seiner Surefire DOM Element Insertion und Ryan Seddon und seinem Artikel über das Einfügen von gestylten Style-Elementen, haben wir das hier:
// Prevent variables from being global
(function () {
/*
1. Inject CSS which makes iframe invisible
*/
var div = document.createElement('div'),
ref = document.getElementsByTagName('base')[0] ||
document.getElementsByTagName('script')[0];
div.innerHTML = '­<style> iframe { visibility: hidden; } </style>';
ref.parentNode.insertBefore(div, ref);
/*
2. When window loads, remove that CSS,
making iframe visible again
*/
window.onload = function() {
div.parentNode.removeChild(div);
}
})();
Fügen Sie dies auf jeder Seite (im <head>) mit dem Problem des weißen Blitzes ein und es wird behoben. Beachten Sie einfach, dass wir hier window.onload verwenden. Wenn Ihre Seite dies ebenfalls irgendwo verwendet, kombinieren Sie sie.
Wie es funktioniert
- Es fügt sofort etwas CSS auf der Seite ein, das alle iframes unsichtbar macht. Sie können keinen weißen Blitz bei einem iframe sehen, der nicht da ist!
- Wenn das Fenster vollständig geladen ist (was bedeutet, dass auch die iframes vollständig geladen sind), wird dieses CSS entfernt, wodurch die iframes wieder sichtbar werden.
Betroffene Browser
Zum Zeitpunkt der Erstellung dieses Artikels konnte ich das Problem in Chrome 11 und Safari 5 reproduzieren (also im Wesentlichen ein WebKit-Problem). Aktuelles Firefox, Opera und IE sind in Ordnung.
Was ist mit... anderen Dingen?
Sie können das Attribut allowtransparency="true" auf den iframe setzen. Sie können den Hintergrund des iframe mit CSS auf transparent setzen. Sie können sicherstellen, dass der Hintergrund im Quellendokument mit dem Hintergrund der Elterndatei übereinstimmt. Nichts davon funktioniert. Dies funktioniert. Nun ja... es funktioniert für Benutzer mit aktiviertem JavaScript, jedenfalls. =)
Wofür steht „­“?
Schauen Sie sich Ryan Seddons Artikel an: http://www.thecssninja.com/javascript/noscope
Es geht darum, dass IE das Style-Tag beim Einfügen entfernt, dies verhindert und es mit einem Zeichen macht, das keine Auswirkung auf die Darstellung hat.
(Das war ein „shy“-Zeichen... was auch immer das bedeutet)
Warum nicht einfach ein <noscript>-Tag mit einem normalen iframe und den iframe per JavaScript für alle anderen hinzufügen?
Es hat meinen HTML-Code bereinigt, es sollte heißen:
Warum nicht einfach ein „noscript“-Tag mit einem normalen iframe und den iframe per JavaScript für alle anderen hinzufügen?
Ich bin mir nicht sicher, ob das helfen würde. Wenn das JS den iframe einfügt, lädt er immer noch und es gibt immer noch einen weißen Blitz. Außer Sie könnten wahrscheinlich den gleichen Trick anwenden, die Sichtbarkeit auszublenden, bis er geladen ist. Es scheint ziemlich unskalierbar zu sein, die Markup für jeden iframe, den Sie einfügen möchten, in den JavaScript-Code aufzunehmen, irgendwie die ol' Streams von Inhalt und Verhalten zu kreuzen.
Sie müssten trotzdem JavaScript verwenden, daher denke ich, dass diese Lösung einfacher ist und sie ohne Bearbeitung der Seite funktionieren sollte, einfach „einfügen und loslegen“.
Hejsa!
Wunderbarer Artikel!
Eine Sache noch: Ich bin sicher, Sie meinen „Sie sehen keinen weißen Blitz bei einem iframe, der nicht da ist!“
Schöner Artikel, aber im Allgemeinen ist die iFrame-Technik so alt. Sie sollten besser darauf achten, andere Methoden wie dynamische Inhalte über PHP zu verwenden.
iFrames bleiben noch eine Weile bestehen, Mann. Ich denke, das ist eine völlig in Ordnung Sache. YouTube-Videos sind iframe-Einbettungen. Wufoo-Formulare sind iframe-Einbettungen. Sie sind wirklich großartig für gehostete Drittanbieter-Inhalte, bei denen Sie die Kontrolle über diese beiden Dinge trennen müssen/wollen.
Die iFrame-Unterstützung von beliebten Webservices wie YouTube, Facebook etc. bedeutet nicht, dass iFrames eine gute Methode zur Handhabung externer Inhalte sind. Es gibt moderne Lösungen wie SOAP oder CURL, um dies zu handhaben. (Entschuldigen Sie mein schlechtes Englisch, ich komme aus Deutschland)
Ich muss Chris zustimmen. Ich arbeite für ein großes Unternehmen und wir haben ein neues, großes SaaS-Produkt, das zu 100 % auf iFrames angewiesen ist.
Sie glauben also, dass YouTube-Videos ihren kopier-und-einfügbaren Video-Code als PHP mit einem CURL-Aufruf bereitstellen sollten?
iFrames sind eine perfekte Möglichkeit, externe Inhalte unterzubringen, und wie Chris sagte, da immer mehr große Unternehmen sie zur Einbettung ihrer Inhalte verwenden (Youtube, Vimeo, Facebook, Twitter...), werden sie noch lange bestehen bleiben.
>> Sie glauben also, dass YouTube-Videos ihren kopier-und-einfügbaren Video-Code als PHP mit einem CURL-Aufruf bereitstellen sollten?
Ja, warum nicht. Es ist auch möglich, eine JSON/XML/Whatever-Schnittstelle zu teilen, die einfach per JavaScript aufgerufen werden kann.
Ich denke, ein iframe macht es Leuten, die nicht im Designbereich tätig sind oder sich Code ansehen, einfach. Für einen großen Prozentsatz der Leute ist es schon schwer genug, einfach nur zu kopieren und einzufügen. Das könnte ein Grund für YouTube gewesen sein, auf iframe-Einbettung umzusteigen, da es weniger kompliziert aussieht.
Ich habe diesen Code zur Verhinderung von Flash auf meiner Website implementiert, sobald ich ihn gesehen habe.
Danke und großartige Arbeit Chris.
Funktioniert das auch, wenn der iframe mit JavaScript eingefügt wurde?
D.h.
Danke, es war sehr nützlich. Ich werde das auf meiner Website verwenden.
Das ist tatsächlich eine großartige Möglichkeit, unerwünschte Styling-Blitze bei Dingen wie geskinnten Dropdowns und benutzerdefinierten Scrollbars zu verhindern. Ich freue mich zu sehen, dass diese Methode an Popularität gewinnt und auch für iframes verwendet wird!
„Beachten Sie nur, dass wir hier window.onload verwenden. Wenn Ihre Seite dies irgendwo auch verwendet, kombinieren Sie sie.“
Warum? Ich dachte, wenn man mehrere Funktionen für ein Ereignis registriert, stapeln sie sich und laufen nacheinander ab. Stimmt das nicht?
Übrigens, wussten Sie, dass man mit einem Skript auf den Inhalt des iframes zugreifen kann? Alles, was Sie brauchen, ist dies
getElementById('myiFrame').contentWindowund es gibt Ihnen das „window“-Objekt dieses iframes zurück. Nun können Sie so etwas tunHier ist ein Fiddle mit zwei Deklarationen von window.onload: http://jsfiddle.net/chriscoyier/gb7gt/ — Sie erhalten nur die zweite. Es mag eine bessere Möglichkeit geben, damit umzugehen. Ich bin ein Noob in JavaScript.
Für den zweiten Teil über den Zugriff auf interne Inhalte des iframes funktioniert das, glaube ich, nur für iframes derselben Domäne.
Chris hat Recht, ‚window.onload‘ kann nur einer Funktionsaufruf zugewiesen werden. Wenn Sie es zweimal verwenden, wird nur der zweite Aufruf ausgeführt. Um zu tun, was Sie vorschlagen, Hassan, würden Sie eine ‚init‘-Art von Funktion verwenden, die bei ‚window.onload‘ ausgeführt wird, und dann mehrere Funktionsaufrufe tätigen, um das von Ihnen beschriebene Stapelverhalten zu erzielen.
Ja, absolut, deshalb habe ich gesagt, dass man im Artikel darauf achten soll und sie kombinieren. Das ist der ideale Weg, wie Sie sagten, eine init-Funktion erstellen und diese aufrufen, die alles enthält, was Sie bei window.onload ausführen möchten.
Der „richtige“ Weg ist, für IE „attachEvent“ und für alle anderen „addEventListener“ zu verwenden. Das erlaubt Ihnen, so viele Rückruffunktionen wie gewünscht an ein Ereignis anzuhängen.
Ich habe es geschafft, diesen weißen iframe-Blitz auf einer Website zu beseitigen, indem ich einfach eine Hintergrundfarbe mit CSS für das iframe-Element verwendet habe. Nicht für Hintergrundbilder geeignet, aber gelegentlich eine Option.
Vielen Dank für diesen guten und saftigen Artikel :)
Das kann definitiv hilfreich sein, wenn ich mit Flash arbeite.
ref = document.getElementsByTagName(‘base’)[0] ||
document.getElementsByTagName(‘script’)[0];
WOW!!!
Was ist mit dem Anwenden einer Klasse auf das HTML- oder Body-Tag, dann das Entfernen beim Laden der Seite? Ich verwende eine ähnliche Technik (ohne die Klasse zu entfernen) für JS-abhängige Stile.
JavaScript im Head
CSS im Stylesheet
Gefällt mir auch.
Obwohl die reine JS-Lösung einfacher zum Kopieren und Einfügen ist, und im Fall von z. B. Wufoo-Formular-Einbettungen (warum ich mich ursprünglich damit beschäftigt habe) die einzige Option ist.
Was ist, wenn Sie dies für eine Seite mit einem iframe verwenden, bei der jeder Klick auf ein Menüelement andere Inhalte im selben iframe lädt? Die Seite lädt nicht neu, nur der iframe-Inhalt. Wie bearbeite ich Ihr Skript, um diese Art von weißem Blitz zu verhindern?
Danke, ich habe eine Stunde lang nach einer Lösung für dieses Problem gesucht! Es sieht nicht gut aus, wenn es sich um ein Zahlungs-Gateway im iframe handelt, Kunden können das Vertrauen ziemlich leicht verlieren.
Ich habe ein Problem damit, dass dies in Fancybox (www.fancybox.net) funktioniert. Fancybox verwendet einen iframe, daher funktioniert dies bis zu einem gewissen Grad. Das einzige Problem ist, dass nach dem Laden der Seite innerhalb von Fancybox das CSS nicht entfernt wird und der Inhalt verborgen bleibt.
Ist jemand mit Fancybox vertraut genug, um mir zu helfen? Ich bin auch neu bei JavaScript und bin mir sicher, dass es eine einfache Anpassung ist, die dies beheben wird, aber ich weiß nicht, wo ich anfangen soll.
Wie füge ich diesen Code zu meiner Seite hinzu? Muss ich ihn innerhalb von Tags einfügen? Oder Tags??
Ich versuche, dies auf einem iframe zum Laufen zu bringen, der in eine Szene innerhalb einer Hype- (http://www.tumultco.com/hype/) Website eingebettet ist. Die Seite mit dem iFrame wird als Szene aufgerufen und daher „lädt“ die Seite nicht wirklich.
Der iframe-Link wird innerhalb eines Inner-HTML-Fensters hinzugefügt.
Kann ich diesen Code anderswo hinzufügen?
Wenn nicht, welche andere oben genannte Antwort passt am besten, vielleicht das Hinzufügen von benutzerdefiniertem CSS innerhalb oder neben dem iframe-Code?
Danke!
Hallo Chris. Danke für die Hilfe. Ich habe den Code in den Head eingefügt, wie Sie sagen. Der Blitz ist weg, aber auch das Video. Nur Ton. Warum?
Mit freundlichen Grüßen,