Przejdź do treści

Skrypty / Menu rozwijane, otwierane, wysuwane - Skrypty

Przykład

Kliknij poniższe nagłówki menu myszką:

Skrypt

Jak zrobić wielopoziomowy system menu z odsyłaczami, które rozwijają lub wysuwają się po kliknięciu lub wskazaniu myszką myszką?

Wymagana wiedza:

Aby wstawić na swoją stronę menu rozwijane, postępuj według poniższych instrukcji:

Utwórz w swoim edytorze HTML nowy dokument. Wklej do niego poniższy kod i zapisz w pliku menu.js:

/**
 * @author Sławomir Kokłowski {@link https://www.kurshtml.edu.pl}
 * @copyright NIE usuwaj tego komentarza! (Do NOT remove this comment!)
 */

function Menu(id, style, otworz, wysun, czasRozwin, czasZwin, czasOtworz, czasZamknij, nieInicjalizuj)
{
	if (typeof czasRozwin == 'undefined' || czasRozwin < 0) czasRozwin = 25;
	if (typeof czasZwin == 'undefined' || czasZwin < 0) czasZwin = 25;
	if (typeof czasOtworz == 'undefined' || czasOtworz < 0) czasOtworz = 250;
	if (typeof czasZamknij == 'undefined' || czasZamknij < 0) czasZamknij = 500;
	
	var url = unescape(window.location.href.replace(/#.*/, ''));
	var base = window.location.protocol + '//' + window.location.host + window.location.pathname.replace(/[^\/\\]+$/, '');
	
	if (style)
	{
		if (style.indexOf(':') < 0)
		{
			document.getElementById(id).className += ' ' + style;
		}
		else
		{
			style = style.replace(/(^\s+|(\s|;)+$)/g, '').split(/\s*;\s*/);
			for (var i = 0; i < style.length; i++)
			{
				style[i] = style[i].split(/\s*:\s*/);
				for (var j = 0, c, property = ''; j < style[i][0].length; j++)
				{
					c = style[i][0].charAt(j);
					property += c == '-' ? style[i][0].charAt(++j).toUpperCase() : c.toLowerCase();
				}
				eval('document.getElementById("' + id + '").style.' + property + ' = "' + style[i][1].replace(/"/g, '\\"') + '"');
			}
		}
	}
	
	for (var i = 0; i < document.getElementById(id).getElementsByTagName('dt').length; i++)
	{
		var dd = new Array();
		var el = document.getElementById(id).getElementsByTagName('dt')[i].nextSibling;
		var nodeName;
		while (el && (nodeName = el.nodeName.toLowerCase()) != 'dt')
		{
			if (nodeName == 'dd')
			{
				el._dt = document.getElementById(id).getElementsByTagName('dt')[i];
				if (otworz)
				{
					el.onmouseover = function()
					{
						clearTimeout(this._dt._timoutID);
						this._dt._displayed = false;
						this._dt.onclick();
					}
					el.onmouseout = function()
					{
						clearTimeout(this._dt._timoutID);
						var dt = this._dt;
						this._dt._timoutID = setTimeout(function () { dt._displayed = true; dt.onclick(); }, czasZamknij);
					};
				}
				dd[dd.length] = el;
			}
			el = el.nextSibling;
		}
		document.getElementById(id).getElementsByTagName('dt')[i]._dd = dd;
		document.getElementById(id).getElementsByTagName('dt')[i]._timoutID = null;
		document.getElementById(id).getElementsByTagName('dt')[i]._displayed = false;
		document.getElementById(id).getElementsByTagName('dt')[i].onclick = function()
		{
			clearTimeout(this._timoutID);
			if (!this._displayed)
			{
				var el = this.parentNode.getElementsByTagName('dt')[0];
				while (el)
				{
					if (el.nodeName.toLowerCase() == 'dt' && el != this)
					{
						el._displayed = false;
						if (czasZwin) display(el, 0);
						else display(el);
					}
					el = el.nextSibling;
				}
			}
			this._displayed = !this._displayed;
			if (this._displayed && czasRozwin || !this._displayed && czasZwin) display(this, 0);
			else display(this);
		};
		if (otworz)
		{
			document.getElementById(id).getElementsByTagName('dt')[i].onmouseover = function()
			{
				clearTimeout(this._timoutID);
				var dt = this;
				this._timoutID = setTimeout(function () { dt._displayed = false; dt.onclick(); }, czasOtworz);
			};
			document.getElementById(id).getElementsByTagName('dt')[i].onmouseout = function()
			{
				clearTimeout(this._timoutID);
				var dt = this;
				this._timoutID = setTimeout(function () { dt._displayed = true; dt.onclick(); }, czasZamknij);
			};
		}
	}
	
	start(document.getElementById(id).getElementsByTagName('dt')[0]);
	
	function start(dt)
	{
		var hide = true;
		var el = dt;
		while (el)
		{
			var nodeName = el.nodeName.toLowerCase();
			if (nodeName == 'dt')
			{
				dt = el;
				hide = true;
			}
			if (nodeName == 'dt' || nodeName == 'dd')
			{
				if (!nieInicjalizuj && el.getElementsByTagName('a').length)
				{
					var active = el.getElementsByTagName('a')[0].href && unescape(el.getElementsByTagName('a')[0].href.replace(/#.*/, '')) == url;
					if (!active)
					{
						var rel = el.getElementsByTagName('a')[0].getAttribute('rel');
						if (rel)
						{
							var matches = (' ' + rel + ' ').match(/\s+Collection\(([^)]+)\)\s+/i);
							if (matches)
							{
								matches = matches[1].split(',');
								for (var k = 0, pos = -1; k < matches.length; k++)
								{
									if (matches[k].charAt(0) == '[' && (pos = matches[k].lastIndexOf(']')) > 0)
									{
										if (new RegExp(unescape(matches[k].substring(1, pos)), matches[k].substring(pos + 1)).test(url))
										{
											active = true;
											break;
										}
									}
									else
									{
										if (/^[\/\\]/.test(matches[k])) matches[k] = window.location.protocol + '//' + window.location.host + matches[k];
										else if (!/^[a-z0-9]+:/i.test(matches[k])) matches[k] = base + matches[k];
										if (unescape(matches[k].replace(/[\/\\]\.([\/\\])/g, '$1').replace(/[^\/\\]+[\/\\]\.\.[\/\\]/g, '').replace(/#.*/, '')) == url)
										{
											active = true;
											break;
										}
									}
								}
							}
						}
					}
					if (active)
					{
						el.className = (el.className ? el.className + ' ' : '') + 'active';
						dt._displayed = true;
						display(dt);
						hide = false;
						var el_parentNode = el.parentNode;
						while (el_parentNode != document.getElementById(id))
						{
							if (el_parentNode.nodeName.toLowerCase() == 'dd')
							{
								var el_sibling = el_parentNode.previousSibling;
								while (el_sibling)
								{
									if (el_sibling.nodeName.toLowerCase() == 'dt')
									{
										el_sibling._displayed = true;
										display(el_sibling)
										break;
									}
									el_sibling = el_sibling.previousSibling;
								}
							}
							el_parentNode = el_parentNode.parentNode;
						}
					}
				}
			}
			if (nodeName == 'dd')
			{
				if (hide) el.style.display = 'none';
				start(el.getElementsByTagName('dt')[0]);
			}
			el = el.nextSibling;
		}
	}
	
	function display(dt, i)
	{
		if (typeof i == 'undefined')
		{
			for (var i = 0; i < dt._dd.length; i++)
			{
				dt._dd[i].style.display = dt._displayed ? 'block' : 'none';
				if (!dt._displayed)
				{
					for (var j = 0; j < dt._dd[i].getElementsByTagName('dt').length; j++)
					{
						dt._dd[i].getElementsByTagName('dt')[j]._displayed = false;
						display(dt._dd[i].getElementsByTagName('dt')[j]);
					}
				}
			}
		}
		else if (i < dt._dd.length)
		{
			var dir = wysun ? !dt._displayed : dt._displayed;
			var n = dir ? i : dt._dd.length - 1 - i;
			dt._dd[n].style.display = dt._displayed ? 'block' : 'none';
			if (!dt._displayed)
			{
				for (var j = 0; j < dt._dd[n].getElementsByTagName('dt').length; j++)
				{
					dt._dd[n].getElementsByTagName('dt')[j]._displayed = false;
					display(dt._dd[n].getElementsByTagName('dt')[j]);
				}
			}
			dt._timoutID = setTimeout(function() { display(dt, i + 1); }, dt._displayed ? czasRozwin : czasZwin);
		}
	}
}

Na samym początku w wyróżnionych miejscach można zmienić domyślne ustawienia konfiguracyjne: czas rozwijania i czas zwijania pojedynczego elementu menu oraz opóźnienie przy otwieraniu i zamykaniu menu (tylko w wersji otwieranej - szczegóły dalej w tym rozdziale). Wszystkie czasy są podane w milisekundach (1 s = 1000 ms). Wartości te zostaną przypisane wszystkim takim blokom menu na stronie, dla których nie określimy inaczej.

Następnie na stronie, gdzie ma być umieszczone menu, należy w nagłówku dokumentu (wewnątrz <head>...</head>) wstawić:

<script src="menu.js"></script>

W wyróżnionym miejscu oczywiście należy podać lokalizację utworzonego wcześniej pliku menu.js. Dalej trzeba na stronie w wybranym miejscu osadzić blok menu za pomocą znaczników listy definicyjnej <dl>...</dl>, np.:

<dl id="menu0">
<dt>Nagłówek 1</dt>
<dd>Element 1.1</dd>
<dd>Element 1.2</dd>
<dd>Element 1.3</dd>
<dt>Nagłówek 2</dt>
<dd>Element 2.1</dd>
<dd>Element 2.2</dd>
<dd>Element 2.3</dd>
<dt>Nagłówek 3</dt>
<dd>Element 3.1</dd>
<dd>Element 3.2</dd>
<dd>Element 3.3</dd>
</dl>
Znaczenie kolejnych elementów jest następujące:
Nagłówek 1, Nagłówek 2, Nagłówek 3
Treść kolejnych nagłówków menu (element <dt>...</dt>). Można tutaj wstawić zwykły tekst, jak również inne elementy - np. obrazek. Aby nagłówek wyglądał jak odsyłacz, można się posłużyć kodem: <a href="javascript:void(0)">Treść nagłówka</a>. Można też wstawić normalny odsyłacz, prowadzący do wybranego dokumentu, jednak wtedy w docelowym dokumencie należy zadbać o wstawienie takiego samego układu menu, ponieważ inaczej nigdy nie będzie dostępu do linków znajdujących się w tej sekcji menu (po kliknięciu menu nie zdąży się rozwinąć, ponieważ natychmiast zostanie wczytana nowa strona - musi zostać rozwinięte na starcie po wczytaniu nowej strony). Zwracam uwagę, że w takim przypadku nie będzie możliwości bezpośredniego zwinięcia takiej sekcji menu bez wczytania nowej strony.
Element...
Rozwijane elementy (<dd>...</dd>), przynależące do kolejnych, poprzedzających nagłówków menu (<dt>...</dt>). Tutaj również nie ma ograniczeń, co do zawartości, którą można umieścić wewnątrz. Mogą to być po prostu odsyłacze ale też inne elementy.

Poniżej wystarczy już tylko umieścić wywołanie skryptu:

<script>
new Menu('menu0');
</script>

...i to wszystko :-). Zwróć tylko jeszcze uwagę na wyróżniony identyfikator menu0 w dwóch ostatnich fragmentach kodu: musi być on w obu miejscach identyczny! Dodatkowo w jednym dokumencie nie mogą istnieć dwa bloki menu o takich samych identyfikatorach. Jeśli chcesz osadzić w jednym dokumencie kilka różnych menu tego typu, postępuj następująco:

  1. Wstaw w nagłówku pliku jeden raz kod:
    <script src="menu.js"></script>
  2. W wybranych miejscach strony osadź bloki menu używając znaczników listy definicyjnej <dl>...</dl>, przy czym każdemu kolejnemu menu nadaj inny identyfikator id="..." - np. id="menu0", id="menu1", id="menu2" itd.
  3. Pod każdym blokiem menu wstaw wywołanie skryptu (ostatni zaprezentowany wcześniej fragment kodu), pamiętając, aby w każdym z nich podać odpowiedni identyfikator (menu0, menu1, menu2 itd.).

Warto nadmienić, że w przypadku kiedy elementy menu zawierają odsyłacze, gałąź menu, w której znajduje się odnośnik do aktualnie wczytanej strony, zostanie na starcie automatycznie rozwinięta. Dzięki temu użytkownik łatwiej odnajdzie punkt w nawigacji, w którym teraz się znajduje. Dodatkowo w takiej sytuacji elementowi <dd>...</dd>, w którym znajduje się bieżący odsyłacz, zostanie przypisana klasa CSS pod nazwą active, dzięki której można dodatkowo wyróżnić aktualną pozycję menu, dodając odpowiednie deklaracje CSS w arkuszu stylów, np.:

#menu0 dd.active {
	font-weight: bold;
}

Prezentowany skrypt obsługuje również wielopoziomowe struktury menu. Zasada zagnieżdżania polega na zbudowaniu najpierw pierwszego, płaskiego poziomu, a następnie wybraniu określonego elementu <dd>...</dd> i umieszczeniu w nim podrzędnej listy <dl>...</dl>, ze swoimi nagłówkami <dt>...</dt> i elementami <dd>...</dd>. Oczywiście ilość poziomów zagnieżdżenia nie jest niczym ograniczona.

W celu osadzenia wielopoziomowego menu, należy powtórzyć wszystkie przedstawione wcześniej kroki. Zmianie ulegnie tylko kod HTML tworzący sam blok menu:

<dl id="menu0">
<dt>Nagłówek 1</dt>
<dd>
	<dl>
	<dt>Nagłówek 1.1</dt>
	<dd>
		<dl>
		<dt>Nagłówek 1.1.1</dt>
		<dd>Element 1.1.1.1</dd>
		<dd>Element 1.1.1.2</dd>
		<dd>Element 1.1.1.3</dd>
		<dt>Nagłówek 1.1.2</dt>
		<dd>Element 1.1.2.1</dd>
		<dd>Element 1.1.2.2</dd>
		<dd>Element 1.1.2.3</dd>
		</dl>
	</dd>
	<dt>Nagłówek 1.2</dt>
	<dd>Element 1.2.1</dd>
	<dd>Element 1.2.2</dd>
	<dd>Element 1.2.3</dd>
	</dl>
</dd>
<dt>Nagłówek 2</dt>
<dd>
	<dl>
	<dt>Nagłówek 2.1</dt>
	<dd>Element 2.1.1</dd>
	<dd>Element 2.1.2</dd>
	<dd>Element 2.1.3</dd>
	<dt>Nagłówek 2.2</dt>
	<dd>Element 2.2.1</dd>
	<dd>Element 2.2.2</dd>
	<dd>Element 2.2.3</dd>
	</dl>
</dd>
</dl>

Przykład:

Czas rozwijania/zwijania

Aby przyspieszyć lub zwolnić rozwijanie/zwijanie pozycji menu, należy powtórzyć wszystkie przedstawione kroki, poza ostatnim (wywołanie skryptu), który tym razem należy wykonać następująco:

<script>
new Menu('menu0', '', false, false, czasRozwin, czasZwin);
</script>
czasRozwin
Czas w milisekundach (1 s = 1000 ms), w którym następuje rozwinięcie pojedynczego elementu menu (<dd>...</dd>). Aby wymusić natychmiastowe rozwinięcie wszystkich elementów, należy podać wartość 0 (zero).
czasZwin
Czas w milisekundach, w którym następuje zwinięcie pojedynczego elementu menu. Aby wymusić natychmiastowe zwinięcie wszystkich elementów, należy podać wartość 0 (zero).

Przykład:

Normalnie pozycje menu są rozwijane począwszy od pierwszej do ostatniej, a zwijane od ostatniej do pierwszej. Można odwrócić te kolejności, dzięki czemu uzyskamy efekt wysuwania:

<script>
new Menu('menu0', '', false, true);
</script>

Przykład:

Czasem przydatne jest wstawienie menu, które otwiera się po wskazaniu nagłówka myszką, a chowa automatycznie po usunięciu wskaźnika myszki z obrębu wybranego fragmentu menu.

<script>
new Menu('menu0', '', true);
</script>

Przykład:

Wskaż poniższe nagłówki menu myszką:

Opóźnienie przy otwieraniu/zamykaniu

Dla tej wersji menu można dodatkowo zmienić opóźnienie, które występuje bezpośrednio przed rozpoczęciem otwierania oraz zamykania menu. Czas ten jest konieczny, aby posługiwanie się takim menu przez użytkownika mogło przebiegać komfortowo. Zbyt małe opóźnienie - zwłaszcza przy zamykaniu - może znacznie utrudnić nawigację!

<script>
new Menu('menu0', '', true, false, -1, -1, czasOtworz, czasZamknij);
</script>
czasOtworz
Czas opoźnienia w milisekundach (1 s = 1000 ms), który upływa od momentu wskazania nagłówka myszką, do rozpoczęcia otwierania menu.
czasZamknij
Czas opoźnienia w milisekundach, który upływa od momentu usunięcia wskaźnika myszki znad wybranego fragmentu menu, do rozpoczęcia jego zamykania.

Pozycja absolutna

Szczególnie dla menu otwieranego dość nieprzyjemną właściwością jest fakt, że przy jego rozwijaniu elementy poniżej są przesuwane w dół. Można temu zapobiec określając odpowiednią pozycję absolutną bloku. Oczywiście można to zrobić bezpośrednio dodając odpowiednie deklaracje CSS. Jednak trzeba przewidzieć, co się stanie, jeśli przeglądarka użytkownika nie będzie obsługiwać JavaScript. Samo menu nadal będzie funkcjonalne pod względem nawigacji, tzn. jego elementy (odsyłacze) będą dostępne, ale oczywiście funkcja rozwijania nie będzie działać. Jest to jednak sytuacja dopuszczalna. Natomiast niedopuszczalne mogłoby być w takiej sytuacji ułożenie wypozycjonowanego absolutnie menu, które zakrywałoby na stałe fragmenty innych elementów strony, które znajdują się poniżej określonej pozycji. Dlatego pozycję należy ustalać nie poprzez atrybut style="..." ani wewnętrzny czy zewnętrzny arkusz stylów, tylko modyfikując fragment kodu wywołujący skrypt:

<script>
new Menu('menu0', 'position: absolute');
</script>

Powyższy sposób pozycjonuje blok menu w miejscu, w którym został wstawiony, ale rozwijanie i zwijanie nie powoduje już żadnych przesunięć pozostałych elementów strony. Można oczywiście dokładnie ustalić pozycję bloku menu, dodając dodatkowe deklarację CSS: 'position: absolute; left: 10px; top: 100px'.

Zamiast wpisywać wprost deklaracje CSS, można podać tylko nazwę klasy CSS:

<script>
new Menu('menu0', 'menu');
</script>

a deklaracje przenieść do arkusza stylów:

.menu {
	position: absolute;
	left: 10px;
	top: 100px;
}

Ponieważ menu otworzy się ponad innymi elementami strony, należy zadbać, aby posiadało ustawione tło. W przeciwnym razie będzie nieczytelne!

Przykład:

Wskaż poniższy nagłówek menu myszką:




Zauważ, że po otworzeniu, menu przykrywa ten tekst.

Inicjalizacja

Domyślnie menu rozwija/otwiera/wysuwa się po załadowaniu strony, tak aby wyświetlić pozycję z odnośnikiem do aktualnie wczytanego dokumentu. Jednak czasami takie zachowanie może nie być pożądane - zwłaszcza w przypadku menu otwieranego z określoną pozycją absolutną. Wtedy po załadowaniu strony, automatycznie otwarte menu zasłania część treści, którą można zobaczyć dopiero po przeciągnięciu wskaźnika myszki nad menu. Aby zapobiec automatycznemu otwieraniu menu po załadowaniu strony, należy określić dodatkowy parametr:

<script>
new Menu('menu0', 'position: absolute', true, false, -1, -1, -1, -1, true);
</script>

Łączenie opcji

Wszystkie z przedstawionych powyżej opcji można ze sobą łączyć, uzyskując w ten sposób dodatkowy efekt, np. następujące wywołanie skryptu:

<script>
new Menu('menu0', 'position: absolute', true, true, 0, 100, 0, 250);
</script>

spowoduje osadzenie wypozycjonowanego absolutnie menu otwieranego w wersji wysuwanej ze zmodyfikowanymi czasami rozwijania/zwijania oraz opóźnieniem przy otwieraniu i zamykaniu. Aby pominąć określenie pozycji, należy po prostu wpisać '' (dwa apostrofy). Aby pominąć ustalenie wersji otwieranej lub/i wysuwanej, należy w ich miejsce zamiast true wpisać false. Aby pozostawić domyślną wartość dowolnego czasu (rozwijania, zwijania, otwierania lub zamykania) można ich po prostu nie podawać - o ile są to ostatnie wartości (końcowe przecinki też należy usunąć)! Natomiast, aby określić np. opóźnienie przy otwieraniu, nie zmieniając jednocześnie domyślnych wartości czasów rozwijania i zwijania, które go poprzedzają, można im przypisać wartość -1. W takiej sytuacji przyjęta zostanie wartość domyślna: new Menu('menu0', 'position: absolute', true, true, -1, -1, 100);

Przykład:

Wskaż poniższy nagłówk menu myszką:




Zauważ, że po otworzeniu, menu przykrywa ten tekst.

Kolekcje dokumentów

Zwykle kiedy publikowany artykuł jest dość długi, dzieli się go na osobne części, dzięki czemu czytelnik nie będzie musiał wczytywać całego tekstu od razu. W takim przypadku w menu umieszcza się najczęściej link tylko do pierwszej części artykułu, a na końcu treści wstawia nawigację stronicującą. Niestety ponieważ adres URL każdej kolejnej części podzielonego artykułu jest różny, właściwa gałąź menu zostanie otwarta i link zaznaczony tylko na pierwszej ze stron. Jeżeli jednak poinformujemy skrypt, które adresy wchodzą w skład kolekcji powiązanych dokumentów, po wejściu na kolejne części artykułu, wszystko będzie działać zgodnie z oczekiwaniami. Aby to zrobić, należy nadać właściwemu odnośnikowi z menu atrybut rel="Collection(...)", w którym podaje się listę adresów URL wszystkich części podzielonego artykułu:

<dl id="menu0">
<dt>Nagłówek 1</dt>
<dd><a href="czesc1.html" rel="Collection(czesc2.html,czesc3.html)">Artykuł stronicowany</a></dd>
<dd><a href="...">Dokument 2</a></dd>
<dd><a href="...">Dokument 3</a></dd>
</dl>

Zwracam uwagę, że w nawiasie nie może być żadnych spacji - nawet po znaku przecinka! Jeśli w nazwie plików z kolekcji znajduje się spacja, należy ją zastąpić przez: %20. Podobnie znaki przecinka, znajdujące się w nazwach plików, należy zastąpić przez %2C, nawias otwierający - %28, nawias zamykający - %29.

Wyrażenia regularne

Występują sytuacje, kiedy dokumentów w kolekcji może być bardzo dużo albo nie wiemy z góry ile, wszystkie jednak pasują do określonego wzorca - np.: /artykul/czesc1.html, /artykul/czesc2.html, /artykul/czesc3.html itd. W takim przypadku dogodniejsze może być dopasowanie adresu przy użyciu wyrażeń regularnych. Aby to zrobić, adres w kolekcji należy objąć nawiasami kwadratowymi, w których wpisuje się treść wyrażenia, np.: rel="Collection([/artykul/czesc\d+\.html])". Również w tym przypadku przypominam, że w nawiasie kolekcji nie może być żadnych spacji, dodatkowych przecinków ani nawiasów okrągłych!

Wygląd

Jeżeli nie odpowiada nam podstawowy wygląd menu, można go zmienić wykorzystując polecenia CSS. W tym celu w pliku menu.css należy wkleić np.:

#menu0 {
	width: 200px;
	margin: 10px;
	padding: 0;
}

#menu0 dt {
	background-color: #888;
	color: #fff;
	font-weight: bold;
	text-align: center;
	cursor: pointer;
	margin: 10px 0 0 0;
	padding: 2px;
}

#menu0 dd {
	background-color: #eee;
	color: #000;
	border-width: 0 1px 1px 1px;
	border-style: solid;
	border-color: #888;
	margin: 0;
	padding: 1px 5px;
}

#menu0 dd.active {
	font-weight: bold;
}

W wyróżnionych miejscach wpisano zdefiniowany uprzednio identyfikator menu. Teraz w nagłówku dokumentu HTML (<head>...</head>), na którym wstawione jest menu, wystarczy wstawić odwołanie do utworzonego właśnie zewnętrznego arkusza stylów:

<link rel="stylesheet" href="menu.css">

Przykład:


Aby uzyskać następujące wielopoziomowe menu otwierane, imitujące tradycyjne menu aplikacji:



należy użyć kodu HTML:

<dl id="menu0">
<dt>Kurs</dt>
<dd>
	<dl>
	<dt><a href="...">HTML</a></dt>
	<dd>
		<dl>
		<dt><a href="...">Dla zielonych</a></dt>
		<dd><a href="...">...</a></dd>
		<dd><a href="...">...</a></dd>
		</dl>
	</dd>
	<dd>
		<dl>
		<dt><a href="...">BODY i META</a></dt>
		<dd><a href="...">...</a></dd>
		<dd><a href="...">...</a></dd>
		</dl>
	</dd>
	<dd>
		<dl>
		<dt><a href="...">Tekst</a></dt>
		<dd><a href="...">...</a></dd>
		<dd><a href="...">...</a></dd>
		</dl>
	</dd>
	</dl>
</dd>
<dd>
	<dl>
	<dt><a href="...">CSS</a></dt>
	<dd><a href="...">...</a></dd>
	<dd><a href="...">...</a></dd>
	</dl>
</dd>
</dl>
<script>
new Menu('menu0', 'menu0', true, false, 0, 0, -1, -1, true);
</script>

oraz dołączyć następujący arkusz CSS:

#menu0, #menu0 dl {
	font-size: 12px;
	position: absolute;
	width: 150px;
	margin: 0;
	padding: 0;
	border-width: 1px;
	border-style: solid;
	border-color: #eee #aaa #aaa #eee;
}

#menu0 dt {
	cursor: pointer;
	margin: 0;
	padding: 0;
	background-color: #888;
	color: #fff;
	text-align: center;
	font-weight: bold;
	font-size: 14px;
	border-width: 1px;
	border-style: solid;
	border-color: #aaa #666 #666 #aaa;
	padding: 4px 5px;
}

#menu0 dl dt {
	background-color: #ccc;
	color: #000;
	text-align: left;
	font-weight: normal;
	font-size: 12px;
	border: 0;
	padding: 0;
}

#menu0 dd  {
	background-color: #ccc;
	color: #000;
	margin: 0;
	padding: 0;
	width: 150px;
	height: 22px;
}

#menu0 dd.active {
	font-weight: bold;
}

#menu0 dt a {
	background: url("submenu.gif") no-repeat 140px 8px;
	padding-right: 20px;
}

#menu0 a:link, #menu0 a:visited {
	display: block;
	color: #000;
	text-decoration: none;
	padding: 4px 5px;
}

#menu0 a:hover {
	color: #fff;
	background-color: #008;
}

#menu0 dl {
	position: absolute;
	border: 0;
}

#menu0 dl dd {
	position: relative;
	left: 151px;
	bottom: 22px;
	border-left: 1px solid #eee;
	border-right: 1px solid #aaa;
}

Aby ustawić kolejne menu otwierane obok siebie, należy wstawić kilka osobnych bloków <dl>...</dl>, a następnie wypozycjonować je w odpowiednim miejscu względem siebie:



Kod HTML:

<div class="menu">
	<dl id="menu1">
	<dt>HTML</dt>
	<dd><a href="...">...</a></dd>
	<dd><a href="...">...</a></dd>
	</dl>
	<script>
		new Menu('menu1', 'position: absolute', true, true, -1, -1, -1, -1, true);
		</script>
	
	<dl id="menu2">
	<dt>CSS</dt>
	<dd><a href="...">...</a></dd>
	<dd><a href="...">...</a></dd>
	</dl>
	<script>
		new Menu('menu2', 'position: absolute; left: 150px', true, true, -1, -1, -1, -1, true);
		</script>
	
	<dl id="menu3">
	<dt>Skrypty</dt>
	<dd><a href="...">...</a></dd>
	<dd><a href="...">...</a></dd>
	</dl>
	<script>
		new Menu('menu3', 'position: absolute; left: 300px', true, true, -1, -1, -1, -1, true);
		</script>
</div>

Arkusz CSS:

.menu {
	position: relative;
}

.menu dl {
	width: 150px;
	margin: 0;
	padding: 0;
	border-width: 1px;
	border-style: solid;
	border-color: #aaa #666 #666 #aaa;
}

.menu dt {
	margin: 0;
	padding: 2px 5px;
	cursor: pointer;
	background-color: #888;
	color: #fff;
	font-weight: bold;
	text-align: center;
}

.menu dd {
	margin: 0;
	padding: 2px 5px;
	background-color: #ccc;
	color: #000;
}

Aby połączyć dwa ostatnie przykłady, wystarczy wstawić wszystkie menu w jednym wspólnym bloku, który musi mieć nadaną pozycję relatywną, a kolejne menu powinny być osadzane następująco:

<div class="menu">
	<dl id="menu0">...</dl>
	<script>
		new Menu('menu0', 'menu0', true, false, 0, 0, -1, -1, true);
		</script>
	
	<dl id="menu1">...</dl>
	<script>
		new Menu('menu1', 'menu0', true, false, 0, 0, -1, -1, true);
		</script>
	
	<dl id="menu2">...</dl>
	<script>
		new Menu('menu2', 'menu0', true, false, 0, 0, -1, -1, true);
		</script>
</div>

Arkusz stylów będzie taki sam, jak w przykładzie wielopoziomowego menu otwieranego (przedostatni powyżej), z niewielkim dodatkiem:

.menu {
	position: relative;
}

#menu1 {
	left: 150px;
}

#menu2 {
	left: 300px;
}

Komentarze

Zobacz więcej komentarzy

Facebook