Zu einem Dokument gehört eine innere Struktur.
Zu mehreren
Dokumenten gehört ein chronologisch-topologisches Miteinander.
Ein Fenster (sichtbarer/unsichtbarer Bildschirmausschnitt) ist auf Betriebssystemebene gekenneichnet durch die zu verwaltenden Fensterdaten und zahlreichen Event-Funktionalitäten des Fensters. Der ( geschützte ) Zugriff auf diese Daten eines Fensters erfolgt mit einem eindeutigen "Window-Handle". Das Betriebssystem verwendet und benutzt grafische Attribute (Device-Context, Hintergrundfarbe, Rand, Ausschnittgröße, Titel, usw.), Kontext-Abhängigkeiten (wie "liegt darunter", "gehört zu", "ist Teil von", "erbt von", "verwaltet andere", usw.) und Ereignisbehandlungen und System-Methoden, die dem Fenster zugeordnet werden (Caret- und Tastatur-Ereignisse, Gesten, Maus-Ereignisse; ist ereignisverarbeitend, ereignisumleitend, zugehörige Aktionen auslösend, usw.).
Bei einem Single Document Interface (SDI, siehe z.B. de.wikipedia: Single Document Interface , erhält jedes Dokument ein eigenes Hauptfenster. Zahlreiche einfache/ältere Programme waren dokumentenzentriert und hatten lediglich ein Dokument (Single Document Interface). Auch für Suchmaschinen sind einzelne Dokumente einfacher zu indizieren (SEO). Die ersten Browser hatten ein "Single Document Interface".
Ein Multiple Document Interface (MDI-Bnutzeroberfläche, siehe z.B. de.wikipedia: Multiple_Document_Interface werden mehrere Dokumente und (sehr viele, oft kleinste!) Fenster verwaltet. So symbolisieren z.B. Registerkarten eine MDI-Bnutzeroberfläche. Typische Entwicklungsumgebungen sind MDI-Applikation.
Systemnahe Computertechnologien unterstützen unterschiedliche Fenster-Technologien. Einfachste Webseiten/Web-Apps können durchaus ohne iFrames, Frames, Manifest, Web Workers, IndexedDB, Web Messaging, Sensorik, .hta-Apps, usw. auskommen. Siehe z.B. "using frames in html5?" . Eingebettete Anwendungen ( Haustechnik, Gebäudetechnik, Gebäudeautomatisierungen, Heizungssysteme, Gefahrenmeldeanlagen, Glasbruchmelder, usw. ) können hinsichtlich der systemnahen Anforderungen an das Betriessystem/Grafiksystem über das "grafische Präsentieren einer Webseite" hinaus gehen.
Beim Erstellen von Webseiten wird untwerschieden zwischen HTML-Frame , Frameset, Inlineframe und Inline Linking ( Hotlinking als Dienstleistung; XSS-Einbetten in Webseite ). Das erlaubte Framing von JavaScript-Code kann zahlreiche Aktivitäten, die im Zusammenhang mit dem Browser stehene, erkunden und protokollieren. Das unerlaubte Framing von Fotos, Videos, usw. kann Urheberrechte verletzen. Frameset haben Vor- und Nachteile. Zahlreiche Nachteile von Frames sind aufgeführt in en.wikipedia: Framing ( World_Wide_Web ) , Frames ( Orelly Webprogramming ).
Jedes Dokument wird mit einer eindeutigen URI ( URL ) identifiziert. Eine einfache, robuste Methode besteht darin, stets nur eine Webseite anzusehen. Eine Präsentation besteht dann in einer Folge von jeweils einem sichtbaren Dokument. Für behinderte Menschen kann die Gleichzeitigkeit von mehreren Dokumenten (ARIA) ein unüberwindbares Hindernis darstellen.
Die gleichzeitige Verfügbarkeit und Ansicht von mehreren (zusammengehörenden) Dokumenten kann (für Sehende) die Übersichlicheit erhöhen ( "Alles im Blick" ). Z.B. kann bei Entwicklungsumgebungen ( MDI, Framesets ) die symbolische Darstellung der möglichen Werkzeuge in verschiedenen Fenstern erfolgen (quasi parallele Sicht auf viele Optionen) und die Entwicklungsarbeiten einfacher, übersichtlicher und bequemer machen können.
Bei einem Einsatz von Frames kommt es wesentlich darauf an, für welchen Zweck Frames verwendet werden. Stehen z.B. SEO-Aspekte im Vordergrund, so können "alte" Robots Interpretationsprobleme mit Frames haben. Stehen z.B. bestimmte Applikationserfordernisse im Vordergrund, so können Frames ein mächtiges Mittel sein. Bei der webbasierten Programmierung (siehe z.B. de.wikipedia: HTML-Frames bietet Frames MDI-Möglichkeiten, indem wechselnde Einzeldokumente in mehreren Frames gleichzeitig dargestellt werden können. Als Dokumententyp der frameset-Seite wird verwendet:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
Für mehrere Dokumente in einem MDI-Kontext gilt die gültige W3C-DTD http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd ( Auszug ). Heute ( 2013 ) werden in einem neuen MDI-Kontext i.a. meist HTML5-Dokumente verwendet.
Jeder Frame kann HTML5 ( oder Seiten mit anderem Dokumententyp ) aufnehmen. Jedes Dokument im Frame hat eine eindeutige URL, die z.B. bei AJAX verwendet werden kann. Als ( gemeinsamen ) Titel der wechselnden Frame-Dokumente zeigt der Browser den Content des Fameset-Title-Tag.
Wird z.B. eine frameset-Seite und mehrere Frames verwendet, so kann die frameset-Seite einzig den Code übernehmen, den alle Frames benutzen. Die zu ladenden Frame-Seiten können z.B. HTML 5 verwenden und ldiglich framespezifischen Code. Die Programmierung wird so natürlich strukturiert. So lässt sich beispielsweise die Navigation zentral in einem HTML-Dokument verwalten und muss nicht auf jeder neuen Seite eingefügt werden. Ein gerade aktueller Frame kann gescrollt werden, während andere Frames davon unbeeinflusst sind. So lässt sich beispielsweise ein Inhaltsframe scrollen, während die Navigation und andere wichtige Bereiche im jeweils eigenen Frame nicht mit scrollen. Die vom Webserver zum Webbrowser zu übertragene Codemenge reduziert sich und es gibt weitere Möglichkeiten der clientseitigen Programmierung und Modularisierung. Durch die zusätzliche "Code-Tiefe" wird das Programmieren von Framesets anspruchsvoller. Frames haben den Vorteil, daß sich über Frames problemlos Inhalte aus unterschiedlichen Quellen bzw. aus verschiedenen Webanwendungen miteinander kombinieren lassen. So könnten Ergebnisse einer Webanwendung in einem Frame in einem anderen Frame angezeigt werden.
Eine Alternative ist, eine Seite als "Master-Seite" zu betrachten und in dieser Seite eingebettete Inlineframe zu verwenden.
Einige Hinweise zu dem iframe-Element stehen unter W3C Working Draft 28 May 2013 ( Kapitel 4.8.2 The iframe element ) W3C html5 #the-iframe-element und/oder HTML 5.1 Nightly A vocabulary and associated APIs for HTML and XHTML ( Editor's Draft 16 June 2013 ) HTML 5.1 Nightly #the-iframe-element und/oder in W3C Candidate Recommendation 17 December 2012 ( Kapitel 10.6 Frames and framesets ) und vorher. Das HTML5 DOM-interface enthält das iframe-Element, d.h. in EINEM HTML5-Dokument können iframes genutzt werden.
Technologisch grob ausgedrückt entspricht ein frame/iframe einem window-Objekt. Praktisch jede Destop-Anwendung hat i.a. eine große Anzahl von Windows. Dies kann mit einem Ereignis-Verfolger ( dies ist kein Befehls-Debugger! ) sichtbar und verstanden werden.
Diese Aufgabe kann genutzt u.a. auch genutzt werden, wie man komplexe Browserunterstützungen experimentell untersuchen kann, indem System-Objekte sichtbar gemacht werden. Trotz uneinheitlicher Browser-Unterstützung wird heute das HTMLIFrameElement vielfach benutzt:
interface HTMLIFrameElement : HTMLElement { attribute DOMString src; attribute DOMString srcdoc; attribute DOMString name; [PutForwards=value] readonly attribute DOMSettableTokenList sandbox; attribute boolean seamless; attribute boolean allowFullscreen; attribute DOMString width; attribute DOMString height; readonly attribute Document? contentDocument; readonly attribute WindowProxy? contentWindow; };
Heute ( 2013 ) werden in einem neuen MDI-Kontext i.a. meist HTML5-Dokumente verwendet. HTML5 ist grob ein nicht abgeschlossener ( SDI-) Standardisierungversuch für EINE Seite in EINEM Fesnster. Jedes HTML5-Dokument (auch .htm, .php, .svg, .gif, .jpg, usw. ) kann in ein zugehöriges Window ( = Frame ) geladen werden. Wichtig ist mime-type-Unterstützung ( rendern von Objekten ).
Welche mime-type unterstützt mein Browser? Siehe browser-mime-type-unterstützung .
Für mehrere Dokumente in einem MDI-Kontext gilt die gültige W3C-DTD http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd ( Auszug ) Heute werden in einem MDI-Kontext i.a. meist HTML5-Dokumente verwendet.
Funktionsbibliotheken zu gängigen Programmiersprachen und Systemumgebungen enthalten Code-Sammlungen. Bei Bibliotheken gibt es einen typischen ( oft hirachischen ) Aufbau der Funktionalitäten.
Was ist anders bei XML-Technologien? Was ist insbesondere anders bei HTML-Technologien mit Frameset und Frames-Fenstern? Bei typischen SDI-HTML-Applikationen includiert jede Seite ( HTML-Dokument ) die benötigten Script-Code-Bibliotheken. Wegen des zustandslosen Protokolls muß der Server für die Verwaltung von Dokumentendaten ( Formulare ) z.B. Cookies für Sessions nutzen. Der Server muß die Session identifizieren und die gegenseitigen Verknüpfungen zwischen einzelnen Seiten übernehmen.
Bei MDI-HTML-Applikationen ( SDI ) ist eine andere Lastenverteilung zwischen Client und Server möglich. Dieses "Programmier-Paradigma für frames" wird nun beispielhaft angerissen.
Ähnlich wie mit dem select-Tag ein gewünschtes Item ausgewählt werden kann, kann mit dem Inhaltsverzeichnis eines Buches (z.B. über die Seitenzahl) der zugehörige Text nachgeschlagen werden. In ähnlicher Weise kann ein linker Frame (FRAME_MENU) das Inhaltsverzeichnis einer Hompage aufnehmen und (mit Hilfe von a-Tags) die zugehörigen Seiten in den rechten Frame (FRAME_INFO) laden.
———————————— ————————————————————————— | | | | | | | FRAME_MENU | FRAME_INFO | | | | | | | | | | | | | | | | | menu.htm | | | | | | | | | | | | a-Tags mit | | | | | | href=...1 | seite_zu_1.htm | | | | | href=...2 | seite_zu_2.htm | | | | | ... | ... | | | | ———————————— —————————————————————————
Als Gedankenexperiment enthalte FRAME_MENU alle Referenzen und mit den a-Tags die Fähigkeit, die zugehörigen Seiten-Inhalten im FRAME_INFO anzuzeigen. Dies entspricht (grob) einem Buch mit Inhaltsverzeichnis (Sitemap). Kommen weitere Seiten (mit eigenen ULR's) hinzu, so werden die URL-Referenzen im FRAME_MENU hinzugefügt. Wird eine Seite nicht mehr gebraucht, so kann z.B. lediglich das a-Tag im FRAME_MENU auskommentiert oder gelöscht werden. Wird das Menü zu unübersichtlich, so kann ein a-Tag eine andere oder weitere Menü-Seite in den FRAME_MENU laden.
Für ECMAScript-Applikationen können framesets geeignet sein, wenn ein MDI-Style gewünscht wird. Das folgende Beispiel teilt den Bildschirmes in 11 Frames. Wird z.B. die Frame-Breite bzw. Frame-Höhe auf 0 gesetzt, so sind diese Teile nicht sichtbar. und kann geeignet sichtbar geschalten werden. Wird ein Frame sichtbar geschalten, so wird der aktuelle (vorher verborgene) Inhalt (ohne HTTP-Request) angezeigt. Natürlich kann jeder Frame zur Laufzeit einen anderen Inhalt erhalten.
Ein Frame-Zugriff kann wahlweise mit dem Frameindex [nullbasiert frames[i]) oder dem Frame-Namen (Frame-Tag-Attribut name="MY_FRAME_NAME") erfolgen. Der frames[0] habe name="FRAME_TOP1". Dann kann ein Zugriff auf das Dokument-Objekt, das im frames[0] ist, erfolgen gemäß var doc0 = frames[0].document; oder var doc0 = frames['FRAME_TOP1'].document;
Die folgende grafischen Darstellungen beschreibt die Einteilung des Bildschirmes in 11 Frames mit einer tabellarischen Darstellung:
i = | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | | | | | | | | | | | | ——————————————————————————————————————————————————————————————————————————————————————————————————————————————— | | | | | | | | | | | | frame[i].name = | TOP1 | TOP2 | LEFT1 | LEFT2 | MENU | LEFT3 | INFO | RIGHT2 | RIGHT1 | BOTTOM2 | BOTTOM1 | | | | | | | | | | | | | ——————————————————————————————————————————————————————————————————————————————————————————————————————————————— | | | | | frameset[0] | frameset[1] | frameset[0] | | | | |
Der Bildschirm habe von oben nach unten: frames[0] (name="TOP1" habe volle waagerechte Breite, Höhe rows = "30, 0, *, 0, 32"), frames[1] (name="TOP2" habe volle waagerechte Breite, Höhe rows = "30, 0, *, 0, 32"), frames[2..8] (name="LEFT1", "LEFT2", "MENU", "LEFT3", "INFO", "RIGHT2", "RIGHT1" haben die gleiche Höhe *, <frameset rows = "30, 0, *, 0,32"), frames[9] (name="BOTTOM2" habe die volle waagerechte Breite, Höhe rows = "30, 0, *, 0, 32"), frames[10] (name="BOTTOM1" habe die volle waagerechte Breite, Höhe rows = "30, 0, *, 0, 32")
Nachfolgend wird die Einteilung des Bildschirmes in 11 Frames als grafische Darstellungen skizziert, wobei die Frame-Bereiche sichtbar und die Bezeichner eingetragen wurden:
Höhen (px) TOP1 | von | TOP2 | | frameset[0] | | LEFT1,LEFT2,MENU,INFO,RIGHT2,RIGHT1 | | | | | | BOTTOM2 | | | | | | | | BOTTOM1 | | | | |
<frameset rows = "30, 0, *, 0,32" cols="*" > ——————————————————————————————————————————————————————————————— | | <frame name= TOP1 | frames[0] | | ——————————————————————————————————————————————————————————————— | | <frame name= TOP2 | frames[1] | | ———————————————————————————————————————————————————————————————
LEFT1 | | LEFT2 | | | | MEMNU | | | Breiten | | | LEFT3 | | | | von | | | | INFO | | | | | frameset[1] | | | | | RIGHT2 | | | | | | | | | | | | RIGHT1 | | | | | | |
<frameset cols = "*, 0,150, 0,500, 0, *" rows="*" > ——————— ——————— —————— ——————— —————————————— ———————— ———————— | | | | | | | | frames[2] | | | | | | | | | | | | | | | | | | | | | | | | frames[3] | | | | | | | | | | | | | | | | | | | | | | | | frames[4] | | | | | | | | | | | | | | | | <frame name= LEFT1 | LEFT2 | MENU | LEFT3 | INFO | RIGHT2 | RIGHT1 | frames[5] | | | | | | | | | | | | | | | | | | | | | | | | frames[6] | | | | | | | | | | | | | | | | | | | | | | | | frames[7] | | | | | | | | | | | | | | | | | | | | | | | | frames[8] ——————— ——————— —————— ——————— —————————————— ———————— ———————— </frameset>
——————————————————————————————————————————————————————————————— | | <frame name= BOTTOM2 | frames[9] | | ——————————————————————————————————————————————————————————————— | | <frame name= BOTTOM1 | frames[10] | | ——————————————————————————————————————————————————————————————— </frameset>
Eine Möglichkeit besteht darin, daß die "Parent-Frameset-Seite" für alle untergeordneten Frames alle nötigen Funktionen zum Informationsaustausch und die Eventbehandlung (zwischen Frames) bereitstellt. Diese Funktionen werden nur einmal (in die "Parent-Frameset-Seite") geladen und stehen jeder aktuelle Seite in einem Frame zur Verfügung.
Will z.B. ein DOM-Element el in einem Frame frames[i] die "top-frameset-Seite" (hier index.htm) nutzen, so braucht die "top-frameset-Seite" den Index i des Frames. Kennt ein Element el "nur sich selbst", so muß in index.htm der frame[i] ausfindig gemacht werden, der das DOM-Element el enthält.
Ist var f = frames[i]; bekannt, so kann mit var win = f.window aus das Window-Objekt und mit var doc = win.document; auf das Dokument-Objekt des Frame zugegriffen werden.
Bei einem Aufruf von var i = top.get_frame_nr(el); in einem Frame-Fenster an index.htm kann el ein Objekt sein, kann el das document-Objekt eines Frames sein, kann el ein bekannter Frame-Name sein. var i = top.get_frame_nr(el); liefert die Nummer i des Frame-Fensters zurück. Ist i bekannt, so können in index.htm z.B. mit Hilfe von frames[i].window.document (beliebige) Manipulationen und Aktionen am Frame-Dokument erfolgen.
Was meint "Fenster"?
... var ifrm = document.createElement("iframe"); ifrm.setAttribute("src", "https://from_frame/1323/frame"), ifrm.style.width = "0px", ifrm.style.height = "0px", ifrm.style.border = "0", ifrm.style.display = "none", document.body.appendChild(ifrm), !function (e, t, n, o, i, r, _) { e.fbq || (i = e.fbq = function () { i.call_meth ? i.call_meth.apply(i, arguments) : i.queue.push(arguments); }, e._fbq || (e._fbq = i), i.push = i, i.loaded = !0, i.version = "2.0", i.queue = [], r = t.createElement(n), r.async = !0, r.src = o, _ = t.getElementsByTagName(n)[0], _.parentNode.insertBefore(r, _)); }(window, document, "script", "https://my/en_US/fbevents.js"), my_buch("init", "413343732388253"), my_buch("trackCustom", "TagView", { tag_id: 1323 });
Jedes HTML-iframe-Tag bettet ein inline-Fenster ( inline-frame, inline-Window ) in die aktuelle Seite. Das iframe-Tag wird innerhalb vom body-Tag benutzt. In das "leere" iframe-Tag, wie z.B.
<iframe name="IFRAME_INFO" src="about:blank"></iframe>
können mit Hilfe von src=... nacheinander Dokumente geladen werden. Die Dokumente sollten von der eigenen http-Domain kommen ( SOP = Same-Origin-Policy ). Beispiel: Lade my.htm in <iframe name="IFRAME_INFO" ... mit Hilfe eines a-Tags.
<a target="IFRAME_INFO" href="my.htm"> lade my.htm </a>
Nach HTML5 kann ein iframe-Tag die Attribute name, height, width, src haben. Die weiteren Attribute, wie sandbox ( allow-forms allow-same-origin allow-scripts allow-top-navigation ), seamless, srcdoc, allowfullscreen sind 2013 bei Browsern noch unzureichend implementiert.
Ist eine HTML-Seite im das iframe-Fenster geladen, so kann diese Seite auf die die parent-HTML-Seite zugreifen, etwa
// ungeprüftes Code-Schnipsel function get_parent_win(f) { // f=frame/iframe var w; if(f.parentNode == null){ f = document.body.appendChild(f); } w = (f.contentWindow || f.contentDocument); if(w && w.nodeType && w.nodeType === 9){ w = (w.defaultView || w.parentWindow); } return w; } function get_parent_url() { return parent !== window ? document.referrer : null; }
Ist iframe das ECMAScript-Objekt zum iframe-Tag, so liefert get_iframe_win(iframe) das Window-Objekt des iframe.
// ungeprüftes Code-Schnipsel function get_iframe_win(iframe){ return iframe_ele.contentWindow || iframe_ele.contentDocument.parentWindow; }
Wie kann die iframe-Parent-Seite auf die Elemente der gerade geladenden iframe-Seite ( src = ... ) mit iframe.onload zugreifen?
// grob etwa: // ungeprüftes Code-Schnipsel var iframe = document.createElement("iframe"); iframe.src = "my.htm"; if (navigator.userAgent.indexOf("MSIE") > -1 && !window.opera) { iframe.onreadystatechange = function() { if (iframe.readyState == "complete") { alert("iframe geladen"); } }; } else { iframe.onload = function() { alert("iframe geladen"); }; } document.body.appendChild(iframe);
// ungeprüftes Code-Schnipsel var arr = parent.document.getElementsByTagName("iframe"); for (var i = 0; i < arr.length; i++) { if (arr[i].contentWindow === window) { alert(arr[i].name); } }
iframe.contentWindow.onload braucht same origin.
iframe.onload ist immer möglich.
iFrams erben die folgenden Methoden:
el.addEventListener(), node.appendChild(), blur, click,
node.cloneNode(), node.compareDocumentPosition(),
el.dispatchEvent(), doCommand, focus, el.getAttribute(),
el.getAttributeNode(), el.getAttributeNodeNS(),
el.getAttributeNS(), el.getBoundingClientRect(),
el.getClientRects(), getElementsByAttribute, getElementsByAttributeNS,
el.getElementsByClassName(), el.getElementsByTagName(), el.getElementsByTagNameNS(),
node.getFeature(), node.getUserData(), el.hasAttribute(), el.hasAttributeNS(),
nodes.hasAttributes(), nodes.hasChildNodes(), node.insertBefore(), node.isDefaultNamespace(),
node.isEqualNode(), node.isSameNode(), node.isSupported(), node.lookupNamespaceURI(),
node.lookupPrefix(), node.normalize(), el.querySelector(), el.querySelectorAll(),
el.removeAttribute(), el.removeAttributeNode(), el.removeAttributeNS(),
node.removeChild(), el.removeEventListener(), node.replaceChild(), el.setAttribute(),
el.setAttributeNode(), el.setAttributeNodeNS(), el.setAttributeNS(), node.setUserData()
Nativ werden die iFrames in den Frame-Array eingefügt. Zu target="IFRAME_INFO" gehört name = "IFRAME_INFO". Das Attribut srcdoc wird 2017 nicht hinreichend unterstütz. Wie kann ein Quelltext-String in iFrame geladen werden? Hier das Prinzip:
Die str_to_iFrame (win, iFrame_name, s) läd den String str in das iFrame-Fenster. Das Handle ifram_hwnd kann global verwendet werden.
// Prinzip: function str_to_iFrame (win, iFrame_name, s) { // ifram_hwnd global var iDoc, win = frames[win] || win, iWin = win[iFrame_name]; iWin.location.href = 'about:blank'; // Chrome brauchts try { iDoc = iWin.contentDocument || iWin.document; // ifram_hwnd = iDoc.open(); iDoc.write(s); iDoc.close(); } catch (e) { alert("ERR: iframe.doc=" + iDoc + "\n" + e); } }
Ein iFrame kann einem 1x1 transparenten Pixel entsprechen.
Wie wird ein unerwünschter Malware-Content in einen iFrame geladen?
Wie wird das ausgeschaltete Javascript manipuliert?
Hier das Prinzip:
<iframe id="clickjacking" onload="disable_javascript()"></iframe> <script> function disable_javascript() { var iframe = document.getElementById('clickjacking').contentWindow.document; iframe.designMode="on"; iframe.body.innerHTML='<iframe id="boese" width="100%"></iframe>'; iframe.getElementById('boese').src = "http://mit_javascript_enabled.com"; } </script>