А теперь рассмотрим создание сложного двухуровневого меню, которое полностью генерируется сценарием. Код сценария будет более универсальным и оформлено в виде двух файлов с расширением js.
Файл menu_prm.js хранит параметры меню. При создании приложений его содержимое можно изменять в зависимости от конкретных задач. В этом файле определяются названия опций и действия для них, цвет и другие параметры. Это переменная(настраиваемая) часть описания меню.
Файл menu_blb.js содержит описание механизма построения и функционирования меню. В нем используются параметры, определенные в первом файле. Это постоянная часть описания меню. Содержимое данного файла можно корректировать по своему усмотрению.
Рассмотрим пример, в котором главное (горизонтальное) меню содержит три опции, первым двум из которых соответствуют вертикальные подменю. Последняя опция является терминальной. Названия опций выбраны так, чтобы можно легко понять, что к чему относится.
В первом файле задаются параметры цвета, шрифта, а также состав названий опций, действия и координаты. Названия опций меню, их позиционирование, действия и содержание статусной строки задаются с помощью массивов. Структура меню определяется двухмерным массивом.
Внимание! Если действие представляет собой не URL-адрес, а код на JavaScript, то он должен начинаться с префикса "javascript: ", за которым следует выражения, разделенные точкой с запятой.
Во втором файле определен ря функций, с помощью которых меню разворачивается и работает. Отображение меню происходит на основе HTML-тегов, определяющих таблицы. Фрагменты HTML-кода, из которых складываются генерирующие строки HTML-документа, определены в виде элементов массива. Позиционирование меню производится с помощью параметров top и left таблицы стилей, которая также генерируется сценарием. Среди множества функций, определенных в этом файле, имеется главная buildMenu(). Вызов ее в сценарии, расположенном в HTML-документе, выводит меню в окно браузера вместе с другими элементами этого документа.
Пишем код файла menu_prm.js с определением параметров меню.
Пишем код файла menu_blb.js.
// JavaScript Document
var ie = document.all ? true : false
var overBox = ''
var timerID
// Заготовки элементов HTML-кода
var barHtml = new Array()
barHtml[0] = '<DIV ID="divbarpos'
barHtml[1] = '" STYLE="position:absolute;left:'
barHtml[2] = 'px;top:'
barHtml[3] = 'px;" onmouseover="openbox('
barHtml[4] = ')" onmouseout="closebox('
barHtml[5] = ')" onclick="clickbox('
barHtml[6] = ')"><TABLE CELLPADDING=0 CELLSPACING=0><TR><TD BGCOLOR="'
barHtml[7] = '"><TABLE CELLPADDING="0" CELLSPACING="1" BORDER="0"><TR><TD CLASS="mnubarpos" ID="mnubarpos'
barHtml[8] = '" WIDTH="'
barHtml[9] = '" BGCOLOR="'
barHtml[10] = '" STYLE="color:'
barHtml[11] = ';font-size:'+cFontSize+';font-family:'+cFontFamily+';">'
barHtml[12] = '</TD></TR></TABLE></TD></TR></TABLE></DIV>'
var boxHtml = new Array()
boxHtml[0] = '<DIV ID="divbox'
boxHtml[1] = '" STYLE="position:absolute;visibility:hidden;left:'
boxHtml[2] = 'px;top:'
boxHtml[3] = 'px;font-family:'+cFontFamily+'" onmouseout="closebox('
boxHtml[4] = ')"><TABLE CELLPADDING=0 CELLSPACING=0><TR><TD BGCOLOR="'
boxHtml[5] = '"><TABLE CLASS="mnubox" ID="mnubox'
boxHtml[6] = '" CELLPADDING="0" CELLSPACING="1" BORDER="0" >'
boxHtml[7] = '<SPAN ID="divboxpos'
boxHtml[8] = '" onmouseover="openboxpos('
boxHtml[9] = ')" onmouseout="closeboxpos('
boxHtml[10] = ')" onclick="clickboxpos('
boxHtml[11] = ')"><TR><TD CLASS="mnuboxpos" ID="mnuboxpos'
boxHtml[12] = '" WIDTH="'
boxHtml[13] = '" BGCOLOR="'
boxHtml[14] = '" STYLE="color:'
boxHtml[15] = ';font-size:'+cFontSize+'">'
boxHtml[16] = '</TD></TR></SPAN>'
boxHtml[17] = '</TABLE></TD></TR></TABLE></DIV>'
function buildMenu() { // построение меню
if (ie) {
buildMenuBar();
buildSubMenu();
if (selfPos) PosMenu();
ResizeSubMenu();
}
}
function buildMenuBar() { // построение горизонтального меню
for (i = 0; i < menu.length; i++){
var s = barHtml[0] + i + barHtml[1] + menu[i][0][3] + barHtml[2] + menu[i][0][4] +
barHtml[3] + i + barHtml[4] + i + barHtml[5] + i + barHtml[6] + clBorder + barHtml[7] + i +
barHtml[8] + menu[i][0][5] + barHtml[9] + clBgInact + barHtml[10] + clFnInact +
barHtml[11] + menu[i][0][0] + barHtml[12];
document.writeln(s);
}
}
function buildSubMenu() { // построение подменю
for (i = 0; i < menu.length; i++){
if (menu[i].length > 1) {
var s = boxHtml[0] + i + boxHtml[1] + menu[i][0][6] + boxHtml[2] + menu[i][0][7] +
boxHtml[3] + i + boxHtml[4] + clBorder + boxHtml[5] + i + boxHtml[6]
for (j = 1; j < menu[i].length; j++) {
var s1 = i + ',' + j
var s2 = i + '_' + j
s += boxHtml[7] + s2 + boxHtml[8] + s1 + boxHtml[9] + s1 + boxHtml[10] + s1 +
boxHtml[11] + s2 + boxHtml[12] + menu[i][0][8] + boxHtml[13] + clBgInact +
boxHtml[14] + clFnInact + boxHtml[15] + menu[i][j][0] + boxHtml[16]
}
s += boxHtml[17]
document.writeln(s)
}
}
}
function PosMenu() {
for (i = 0; i < menu.length; i++) {
barCurr = document.all['divbarpos' + i]
if (i > 0) {
barPrev = document.all['divbarpos' + (i - 1)]
barCurr.style.left = barPrev.offsetLeft + barPrev.offsetWidth - 1
}
if (menu[i].length > 1) {
boxCurr = document.all['divbox' + i]
boxCurr.style.pixelTop = barCurr.offsetTop + barCurr.offsetHeight - 1
boxCurr.style.pixelLeft = barCurr.offsetLeft
}
}
}
function ResizeSubMenu() {
for (i = 0; i < menu.length; i++) {
if (menu[i].length > 1 && menu[i][0][8] <= 0) {
el = document.all['mnubox' + i]
w = document.all['divbarpos' + i].offsetWidth
if (el.offsetWidth < w) el.style.width = w
}
}
}
function openbox(x) {
paintLayer('mnubarpos' + x, active = true)
showLayer('divbox' + x)
for (i = 0; i < menu.length; i++) if (i != x) closebox(i, 0)
overBox = 'divbox' + x
window.status = menu[x][0][2]
}
function closebox(x, timeout) {
paintLayer('mnubarpos' + x, active = false)
clearTimeout(timerID)
if (timeout == 0) hideLayer('divbox' + x)
else timerID = setTimeout('hideLayer("divbox' + x + '")', closeTimeout)
overBox = ''
window.status = defaultStatus
}
function clickbox(x) {
clickMenu(menu[x][0][1])
}
function openboxpos(x, y) {
paintLayer('mnuboxpos' + x + '_' + y, active = true)
overBox = 'divbox' + x
window.status = menu[x][y][2]
}
function closeboxpos(x, y) {
window.status = defaultStatus
paintLayer('mnuboxpos' + x + '_' + y, active = false)
}
function clickboxpos(x, y) {
clickMenu(menu[x][y][1])
}
function clickMenu(s) {
if (s.indexOf('javascript:') == 0) eval(s);
else if (s != '') window.location.href = s;
}
function paintLayer(layerID, active) {
if (layer = document.all[layerID]) {
if (active) { clBg = clBgAct; clFn = clFnAct }
else { clBg = clBgInact; clFn = clFnInact }
layer.style.backgroundColor = clBg
layer.style.color = clFn
}
}
function showLayer(layerID) {
if (layer = document.all[layerID]) layer.style.visibility = 'visible'
}
function hideLayer(layerID) {
if (layer = document.all[layerID] && (overBox != layerID)) document.all[layerID].style.visibility = 'hidden'
}
Чтобы создать меню, в HTML-документе пишем следующие строки:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Сложное двухуровневое меню</title>
<script src="menu_prm.js"type="text/javascript"></script>
<script src="menu_bld.js" type="text/javascript"></script>
<script type="text/javascript">buildMenu()</script>
</head>
<body>
</body>
</html>
Здесь buildMenu() – функция определение которой находится в файле menu_blb.js. Она выводит на экран меню в соответствии с параметрами, заданными в файле menu_prm.js.
В окне веб-браузера это будет выглядеть ТАК.