Jak możemy wyczytać na stronach kursu tworzenia stron w html tworzenie stron z wykorzystaniem ramek jest uznawane za schyłkowe. Ogólnie jak zwykle chodzi o semantykę. Strona zbudowana na ramkach nie stanowi całości, a tylko oddzielone od siebie części. Powoduje to, że cała semantyka bierze w łeb :) W dzisiejszych czasach, gdzie technologie takie jak AJAX są chlebem powszednim wykorzystanie ramek jest więc nieco "przestarzałe". Dobrze jest jednak poznać tajniki rządzące ramkami. Po pierwsze dla nauki, po drugie - czasami to się bardzo przydaje (ot choćby w przypadku złomu IE6 i obsługi select przez tą przeglądarkę).
Strona składająca się z ramek zbudowana jest z co najmniej 3 dokumentów:
Każdą ramkę możemy traktować jak okno, w którym znajduje się dokument. Tak więc możemy na niej przeprowadzać dowolne operacje, które przeprowadzaliśmy na zwkłych dokumentach. Na przykład możemy posłużyć się metodą document.write by wypisać w ramce tekst, czy dowolną inną metodą dostępną dla obiektu document.write. Więcej - możemy odwoływać się do funkcji i zmiennych, które są utworzone w dokumentach znajdujących się w innych ramkach.
Aby odwołać się do ramki opisującej zestaw ramek (frameset) korzystamy z instrukcji top lub parent.
Do ramek podrzędnych odwołujemy się poprzez ich nazwę (NAME).
Wszystkie ramki są zgrupowane w tablicy frames, aby pobrać liczbę zdefiniowanych ramek wystarczy odczytać długosć tej tablicy.
Przykłądowy układ ramek:

Zestaw ramek przedstawiony na rysunku tworzmy przez zastosowanie kodu:
<html> <head> <title>strona z ramkami</title> </head> <frameset cols="20%,*"> <frame scrolling="auto" name="menu" src="menu.html"> <frame scrolling="auto" name="tresc" src="strona.html"> <noframes> <body> zawartość strony dla przeglądarek nie obsługujących ramek </body> </noframes> </frameset> </html>
Oczywiście powyższy schemat wymaga dodatkowo dwóch stron - menu.html i strona.html.
Jeżeli nie rozumiesz powyższego kodu, zapraszam do lektury.
Instrukcja parent określa dokument definiujący zestaw ramek, czyli stojący najwyżej w zestawie ramek (na rysunku pokazany jako frameset).
Aby odwołać się do dowolnej ramki z naszego zestawu skorzystamy z instrukcji:
parent.frames['menu']; //odwołanie do ramki poprzez jej nazwę parent.frames[0]; //0 oznacza numer 1 ramki parent.menu; //odwołanie do ramki poprzez jej nazwę parent.frames['tresc']; parent.frames[1]; parent.tresc;
W powyższym przykładzie tresc jest nazwą ramki.
Jeżeli ramki są zagnieżdzone w innych ramkach, wówczas odwołujemy się do kolejnych ramek, w kolejności w jakiej są stworzone, np:
parent.tresc.innaramka //lub parent.frames[1].frames[0]
Często inne osoby mogą dawać odnośniki do podstron twojego serwisu, sprawiając tym samym, że twoje strony będą wyglądały, jakby były w ich serwisach. Jak już wiemy na samej górze ramek jest dokument parent. Jeżeli ktoś "podbiera" twoją stronę, wówczas wyświetlana jest ona w ramce potomnej.
Dzięki Javascript możemy zmusić przeglądarkę, aby zawsze wyświetlała twoją stronę w pełnym oknie, a nie w ramkach. Wystarczy, że sprawdzimy właciwość location danej strony (self) z właściwością location najwyższego okna w hierarchii:
if (top.location != self.location) //jeżeli dana strona (self) nie znajduje się na szyczycie hierarchii... top.location = self.location //wówczas ją tam umieść
Sytuacja może być też odwrotna. Powiedzmy, że nasz serwis zbudowany jest z ramek. Lewa ramka (np. menu) zawiera informacje, które są potrzebne dla prawej ramki. Jednak wyszukiwarki częstokroć indeksują także podstrony serwisu i tym samym dają możliwość wyświetlania pojedyńczych podstron serwisu. Wynikiem jest to, że dana podstrona będzie wyświetlana bez pozostałych ramek naszego serwisu.
Dzięki Javascript możemy zmusić przeglądarkę, aby wyświetlała nasze strony w zestawie naszych ramek. Wystarczy, ze na każdej stronie naszego serwisu wstawimy kod:
if (top.location == self.location) //jeżeli dana strona znajduje się na szyczycie hierarchii... top.location = 'frameset.html' //to ładujemy tam zestaw ramek
Częstokroć w jednej ramce znajduje się odnośnik, którego kliknięcie powoduje załadowanie strony w innej ramce. Można oczywiście coś takiego zrobić w zwykłym HTML (poprzez zastosowanie atrybutu target), jednakże uzyskanie tego w Javascript przynosi nam wiele korzyści? Jakich? Jedna z nich to ta, że metodę tę w łatwy sposób można wykorzystać, by link ładował strony nie w pojedyńczej ramce, a w wielu naraz. Poza tym atrybut target jest zły ^^ (czemu?... poszukaj w necie).
Funkcja, która załaduje strony do kilku ramek może mieć postać:
function zmienStrone() {
for (x=0; x<arguments.length; x++) {
parent.frames[x].document.location.href = arguments[x];
}
Możemy w łatwy sposób odwoływać się do funkcji znajdujących się w innych ramkach. Na przykład gdy w pierwszej ramce znajdować się będzie funkcja np. Alarm(), to aby odwołać się do niej z innej ramki skorzystamy z instrukcji:
parent.frames[0].Alarm()
Za pomocą metody document.write() w łątwy sposób możemy dynamicznie generować zawartość strony znajdującej się w określonej ramce. Na przykład, jeżeli chcemy wyświetlić jakiś napis w ramce tresc skorzystamy z instrukcji:
parent.tresc.document.write('To jest jakaś treść');
Przykładowa funkcja realizująca to zadanie może mieć postać:
function generujTresc(tytul,tresc) {
var tekst = '';
tekst += '<html>';
tekst += '<head><title>'+tytul+'</title></head>';
tekst += '<body>';
tekst += '<h3>' + tytul + '</h3>';
tekst += tresc;
tekst += '</body>';
tekst += '</html>';
parent.tresc.document.write(tekst);
parent.tresc.document.close();
}
Dzięki metodzie close() znajdującej się na końcu naszej funkcji nowo generowana strona będzie tworzona od początku, a nie dopisywana do poprzedniej. Jeżeli nie zastosowalibyśmy tej metody, kolejna strona zamiast zastąpić poprzednią była by dopisana do istniejącej.