РЕКЛАМА |
Иерархическое (многоуровневое)
< Часть 4
|
Реклама
|
В Листинге 2 определены (в смысле, представлены все необходимые функции для создания) три объекта, определяющие содержание иерархического меню. Наиболее простой из них объект MenuItem, который представляет собой конечный пункт меню; он определяет реакцию браузера на щелчок мышки. Этот объект имеет шесть полей и не имеет методов. Его конструктору передаются три аргумента (title, anchor, alt), инициализирующих три из шести полей; остальные поля заполняются по умолчанию. Смысл полей таков:
name имя пункта меню, которое будет отображаться на экране. Инициализируется параметром title конструктора. Для предохранения имени от "блуждающих" символов > и < оно обрабатывается функцией SafeString, заменяющей эти символы на "безопасные" синонимы ( a ссылка (URL), на которую необходимо перейти, или код на JavaScript, который надо выполнить. В последнем случае строка предваряется строкой "javascript:" или "jscript:". Инициализируется параметром anchor контруктора. alt строка подсказки (tip), появляющаяся после остановки курсора мышки на пункте меню, соответствующая параметру title практически любого тэга HTML. Может быть пустой строкой (""). Инициализируется параметром alt контруктора. objname имя объекта (вернее тип). Т.к. пунктом меню может быть не только объект MenuItem, но и MenuBox, определяющий подменю, необходима информация для индентификации. Самый простой способ хранить тип объекта в строке с одним и тем же именем (объект MenuBox тоже имеет поле objname). Для объекта MenuItem эта строка равна "item". idname уникальное имя объекта, равное "nxx" (xx число). Уникальность достигается присваением числа, равному инкременту (увеличенному на 1) глобальной переменной nmb, т.о. что каждый пункт меню отличается от предыдущего как минимум на единицу. owner объект-владелец пунктом меню, заполняется при добавлении пункта в состав подменю (см. ниже). Для определения (резервирования) поля присваивается нулевая ссылка (null). Следующим объектом, определенным в файле kcmmenu.js, является MenuBox. Этот объект представляет собой контейнер для объектов MenuItem и объектов подменю MenuBox. Его контруктор function MenuBox(name), где name имя подменю. Поля и методы объекта MenuBox таковы. name имя пункта меню, которое будет отбражаться на экране. Инициализируется параметром name контруктора. Для предохранения имени от "блуждающих" символов > и < обрабатывается функцией SafeString (см. выше). alt строка подсказки (tip) (см. MenuItem.alt). По умолчанию задана как "Goto submenu"; при необходимости можно изменить. objname имя объекта (см. MenuItem.objname); для объекта MenuBox равно "box". idname уникальное имя объекта (см. MenuItem.idname). owner объект-владелец пунктом меню (см. MenuItem.owner). item массив объектов (MenuItem и MenuBox), для которых данный объект является контейнером. Инициализация этого поля рассмотрена выше count текуший размер массива item; для нового объекта равен 0. addItem метод (функция) добавления пункта меню (или подменю) в контейнер. Методу присваивается ссылка на функцию addMenuItem(item) (где item объект типа MenuItem или MenuBox). Функция addMenuItem присваивает полю owner объекта item указатель на объект контейнер this (напомним, что в this передается ссылка на объект, чей метод используется, т.е. ссылка на самого себя). Т.о. контейнер "говорит" своим элементам, что он является их владельцем. После этого item добаляется в массив объектов MenuBox.item, увеличивая при этом размер массива count. getItem метод (функция) получения пункта меню (или подменю) по имени. Методу присваивается ссылка на функцию getMenuItem(name) (где name имя пункта меню, объект которого (MenuItem или MenuBox) необходимо получить). Функция getMenuItem просматривает поля idname всех своих элементов. Если это поле не равно имени запрошенного элемента, а тип элемента равен MenuBox (objname=="box"), то вызывается функция getItem этого элемента для просмотра в нем. Т.о. просматривается вся ветка подчиненных объектов. Если объект с заданным именем не найден, возвращается пустая ссылка (null).
|
Реклама
Каждому сайту - механизм организации собственной ленты новостей бесплатно! |
Наконец, последним объектом, определенным в файле kcmmenu.js, является MenuBar. Этот объект представляет собой контейнер для объектов MenuBox нулевого уровня, всегда отображаемых в полосе меню экрана. Его контруктор function MenuBar() не имеет аргументов. Поля и методы объекта MenuBar таковы. name имя меню; по умолчанию присваивается "MMB" (Main Menu Bar). objname имя объекта (см. MenuItem.objname); для объекта MenuBar равно "bar". owner равен null, т.е. не имеет владельца. item массив объектов MenuBox, для которых данный объект является контейнером. Инициализация этого поля рассмотрена выше count текущий размер массива item; для нового объекта равен 0. addMenu метод аналогичен MenuBox.addItem и отличается только именем. getSubMenu метод (функция) получения ссылки на подменю по имени. Метод аналогичен MenuBox.getItem и отличается лишь тем, что проверяет тип возвращаемого значения (ссылка возвращается только в том случае, если objname=="box"). getMenuItem метод полностью аналогичен MenuBox.getItem. Построенный, используя эти объекты (см. примечание о файле kcmmenu.js), глобальный объект menu не доступен браузеру, отображаемому информацию. Он находится в памяти (образно) машины сценариев (Scripting Engine), которая связывает html-код с событиями от html-тэгов. Для связи меню с html-кодом необходимо определить html-тэги, содержание визуальное представление меню на экране. Для этого нам необходимо по ходу отображения документа браузером изменить его, чтобы включить меню в отображаемую информацию. Машина сценариев имеет несколько возможностей менять содержание документа. Одной из них является функция write (в нотации JavaScript) объекта document глобального объекта window. Выполнение этой функции приводит к записи в документ в месте ее применения строки (или строк), передаваемой ей в качестве аргумента. Для "вписывания" меню в html-страницу используется функция ConstructMenu(menu) (и ряд вспомогательный функций), которой передается ссылка на объект меню. Вообще, по большому счету, передача функции ссылки на menu не обязательная, т.к. menu глобальный объект; здесь это сделано в целях универсальности и наглядности. ConstructMenu создает строковое представление тэга DIV (т.е. html-код) с классом menu и id=MainMenuBar (класс определяет форматирование объекта и описан, в данном случае, в файле menu.css). Этот DIV ассоциируется в объектом menu (типа MenuBar). В этот DIV вставляются контейнеры текста SPAN, отвечающие за подменю нулевого уровня. Строковое представление этих SPAN определяется полем name этих подменю, параметр name полем idname (уникальным!), class=menu, id=submenu. Разделяются пункты полосы меню вертикальной чертой, "обернутой" в тэг SPAN с классом menudelim. Для каждого пункта, представляющего собой указатель на подменю, вызывается функция построения подменю ConstructMenuBox(submenu). При построении (записи в строку html-кода) всего меню, оно вписывается в документ функцией document.writeln. В конце вызывается функция инициализации меню. ConstructMenuBox делает тоже самое, что и ConstructMenu, только для подменю. Для этого после проверок на корректность вызова функции она увеличивает глобальную переменную zindex на 1, изначально заданную равной параметру z-index стиля div.menu. Это значение потом присваевается параметру z-index стиля тэга DIV, отвечающего за подменю. Таким образом достигается правильный z-порядок следования подменю; подменю высшего уровня (т.е. находящиеся дальше от корневых подменю нулевого уровня) будут всегда находится сверху подменю низшего уровня. DIV подменю записывается с парамтрами: class = submenu, id = submenu, name = idname подменю. Параметры стиля определяют z-index (см. выше), перемещаемость элемента по экрану (position:absolute), невидимость (visibility:hidden, т.к. первоначально подменю не видны) и ширину (width:1000px). Ширина задается заведомо большой, она впоследствии настраивается на ширину тэгов SPAN, входящих в меню. При отсутствии ширины в описании стиля, это свойство перестает быть доступным из JavaScript. Затем в этот DIV вставляются контейнеры текста SPAN, отвечающие за пункты меню. Строковое представление этих SPAN определяется полем name этих пунктов, параметр name полем idname (уникальным!), параметр title полем alt, class=nonact (первоначально неактивный), id=menupunkt. Разделяются пункты подменю разрывом строки (<br>). Если пункт меню является подменю высшего уровня (для этого проверяется его поле objname на соответсвие строке "box"), то для него рекурсивно вызывается ConstructMenuBox с параметром равным ссылке на объект этого пункта-подменю. В конце это подменю вписывается в html-документ (напомним, что оно невидимо изначально). Глобальная переменная zindex уменьшается на 1, возвращая прежнее значение; это заставляет подменю одних уровней иметь одинаковый приоритет при прорисовке на экране. Таким (вобщем-то нехитрым) образом один вызов функции ConstructMenuBox из ConstructMenu для подменю нулевого уровня за счет рекурсии строит всю ветку. Функция InitMenu (напомним, что она вызывается из ConstructMenu) создает два глобальных массива всех тэгов меню DIV и SPAN (вернее, их описаний), которые используются при обработке событий от элементов меню. Эти массивы содержат не все эти тэги DIV и SPAN документа, а только тэги меню, потому что документ фактически еще не составлен (не подготовлен для просмотра и статистики). Таким образом, между прочим, отсекаются все ненужные нам тэги остальной части документа, не отвечающие за меню. Затем для всех тегов DIV ищется их соответствие во всех объектах подменю главного меню. Для этого методом menu.getSubMenu(DIV.name) ищется подменю с полем idname=DIV.name. Такое соответствие должно быть обязательно, ибо все тэги DIV в массиве строились на основании соответствующих подменю. В противном случае этот тэг пропускается. Если соответствие найдено, просматриваются все пункты меню, входящие в данное подменю. Для этого простым перебором в массиве ищется SPAN с параметром name равным полю idname данного пункта. Максимальная ширина всех просмотренных пунктов подменю назначается шириной данного подменю. Такая процедура исключает согласование ширины пункта меню и ширины подменю, вернее ширины тэга SPAN пункта меню и ширины тэга DIV подменю. Если же Вы решили их согласовать, например, параметром width стилей, то эту процедуру можно убрать. [> далее >] © 2000, Сергей Кузнецов
|
Реклама
ВАКАНСИИ (Компьютеры, Интернет). |
Главная / Разное / JavaScript-меню | ^^^ |
© iD, 2000
|