html, dwie ramki ,ładowanie stron z jednej do drugiej
<iframe>
) atrybut name="content"
target="content"
albo w JS zmienić parent.frames['content'].location.href = 'strona.html';
<frameset>/<frame>
– metoda historyczna, dziś deprecated<iframe>
– nadal w HTML 5, ale zalecany wyłącznie do wstawiania wycinków (film, mapa)<frameset>
(przykład edukacyjny)<!DOCTYPE html>
<html>
<head><title>Dwie ramki (frameset)</title></head>
<frameset cols="25%,75%">
<frame src="menu.html" name="menu">
<frame src="welcome.html" name="content">
</frameset>
</html>
menu.html
<a href="page1.html" target="content">Strona 1</a><br>
<a href="page2.html" target="content">Strona 2</a>
Mechanizm – atrybut target
informuje przeglądarkę, by wskazany dokument załadować w ramce nazwanej content
.
<iframe>
+ flexbox (layout w CSS)<!DOCTYPE html><html lang="pl">
<head>
<meta charset="utf-8">
<style>
body{margin:0;font-family:sans-serif}
.wrap{display:flex;height:100vh}
nav {width:220px;background:#f4f4f4;padding:1rem}
iframe{flex:1;border:none}
</style>
<script>
function loadPage(url){
document.querySelector('iframe').src = url; // JS
}
</script>
</head>
<body>
<div class="wrap">
<nav>
<a href="#" onclick="loadPage('page1.html')">Strona 1</a><br>
<a href="#" onclick="loadPage('page2.html')">Strona 2</a>
</nav>
<iframe name="content" src="welcome.html"></iframe>
</div>
</body>
</html>
• Można też pozostać przy linkach i target="content"
(bez JS).
• Dostęp między ramkami możliwy tylko w tej samej domenie (Same-Origin Policy).
<nav>
<a href="#" data-page="page1.html">Strona 1</a>
<a href="#" data-page="page2.html">Strona 2</a>
</nav>
<main id="view"></main>
<script>
document.querySelectorAll('nav a').forEach(a=>{
a.onclick = e=>{
e.preventDefault();
fetch(a.dataset.page)
.then(r=>r.text())
.then(html=>document.getElementById('view').innerHTML=html)
.catch(()=>alert('Błąd ładowania'));
};
});
</script>
Plus history API (pushState
) dla poprawnego działania przycisku Wstecz i SEO – fundament Single Page Applications.
// z ramki potomnej do nadrzędnej
parent.frames['content'].postMessage({cmd:'zmienKolor',val:'#ff0'}, '*');
// odbiór w dokumencie nadrzędnym
window.addEventListener('message', e=>{
if(e.data.cmd==='zmienKolor')
document.body.style.background=e.data.val;
});
postMessage
umożliwia kontrolowaną wymianę danych także między różnymi domenami (jeżeli druga strona wyrazi zgodę).
frameset/frames
od 2017 r. usunięto z specyfikacji HTML 5 (status obsolete), większość narzędzi build/linters zgłasza błąd. iframe
żyje, lecz coraz częściej blokowany nagłówkami CSP (Content-Security-Policy: frame-ancestors
) i X-Frame-Options
(walka z click-jackingiem). name
i target
muszą być identyczne znak-w-znak (wielkość liter ma znaczenie w XHTML). "_self"
, " _blank"
, " _parent"
, "_top"
można wskazać dowolną nazwę ramki/iframe. X-Frame-Options: DENY/SAMEORIGIN
, który całkowicie uniemożliwi osadzenie. X-Frame-Options
lub frame-ancestors
. <template>
jako lżejsza alternatywa dla pełnego SPA. Stare <frameset>
rozwiązuje problem dwoma atrybutami (name
/ target
), lecz zostało wycofane ze standardu. <iframe>
pozostaje, ale w nowym kodzie zaleca się zastąpić go mechanizmem AJAX/SPA albo renderowaniem po stronie serwera. Jeśli jednak ramki są wymagane (np. konserwacja starego systemu), pamiętaj o zasadzie same-origin, nagłówkach bezpieczeństwa i ograniczeniach SEO.