Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Web-программирование - это просто!


Новинка интернет магазина: Анализ цен поставщиков v1.0 для 1С:Бухгалтерия 8.2 конфигурации Бухгалтерия предприятия 2.0


Новое на сайте Программирование - это просто! (www.easyprog.ru):

В платном разделе

В бесплатном разделе

Добрый день, уважаемые подписчики!

Тема сегодняшнего выпуска: «Java Script(JS): Библиотека визуальных компонентов. Очень мощное меню. Продолжение.

 

Скачать файлы с описанными классами можно  здесь(версия 1.6).

Для углубленного изучения web-программирования (язык PHP и написание своей собственной CMS) советую подписаться на платный раздел (см. анонсы раздела "Пишем Easy CMS").

 

Сегодня мы вернемся к мощному меню из библиотеки визуальных компонентов. Мы уже рассматривали как сделать горизонтальное меню. Теперь сделаем вертикальное. Для этого нужно просто свойству _arranging класса CXMyBrMenu присвоить константу arVertical. Рассмотрим все это на примере:

<HTML>

    <head>

      <title></title>

        <LINK HREF="menu.css" REL="stylesheet" TYPE="text/css">

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrBase.js">

        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrGlobalVars.js">

        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrGlobalProc.js">

        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrVisual.js">

        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrTrees.js">

        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="XBrMenus.js">

        </SCRIPT>

    </head>

 

    <BODY>

        <div id="1">

           

        </div>

        <div id="2">

            div2

        </div>

        <SCRIPT Language="JavaScript" type="text/javascript">

       

            function CXMyBrMenu(object) {

                CXBrMenu.call(this,object);

                this._on_node_click=CXMyBrMenu_on_node_click;

            }

               

            function CXMyBrMenu_on_node_click(id,level_node) {

                a=document.getElementById("2")

                a.innerHTML="Вы выбрали пункт "+id+" уровень "+level_node;

                alert(id+"   "+level_node)

            }

       

            var ob=new CXMyBrMenu(document.getElementById("1"))

            ob._arranging=arVertical

 

            ob._nodes._add(new CХBrTreeNodes(null,"Проба",null),"Главное",null)

            ob._nodes._add(new CХBrTreeNodes(null,"Проба1",null),"Второй пункт",null)

            ob._nodes._add(null,"Третий пункт",null)

            ob._nodes._add(null,"Четвертый пункт",null)

            ob._nodes._objects_list[0]._nodes._add(null,"Подпункт",null)

            ob._nodes._objects_list[0]._nodes._add(null,"Еще подпункт",null)

            ob._nodes._objects_list[1]._nodes._add(null,"123",null)

            ob._nodes._objects_list[1]._nodes._add(null,"456",null)

            ob._nodes._objects_list[1]._nodes._add(null,"789",null)

            ob._nodes._objects_list[0]._nodes._add(new CХBrTreeNodes(null,"Проба1",null),"Подменю",null)

            ob._nodes._objects_list[0]._nodes._objects_list[2]._nodes._add(null,"Первый пункт подменю",null)

            ob._nodes._objects_list[0]._nodes._objects_list[2]._nodes._add(null,"Второй пункт подменю",null)

            ob._nodes._objects_list[0]._nodes._objects_list[2]._nodes._add(new CХBrTreeNodes(null,"+++",null),"Очень низкое подменю",null)

            ob._nodes._objects_list[0]._nodes._objects_list[2]._nodes._objects_list[2]._nodes._add(null,"Ну вот и все",null)

 

            ob._draw()

        </SCRIPT>

    </BODY>

</HTML>

 

 

Теперь меню будет выглядеть так:

Тема сегодняшнего выпуска: «Java Script(JS): Библиотека визуальных компонентов. Очень мощное меню. Продолжение.

 

Теперь немного заглянем во внутренности класса CXMyBrMenu, посмотрим, например, как формируется меню:

 

function CXBrMenu_out_tree(level_node,nodes) {

    if(level_node>_max_tree_items) {alert("Зависло!!!"); return ""}

    var Outline="";

    var totlen=0;

    var len_m=nodes._max_name_length();

 

    //Определяем расположение текущего узла меню: 0-ой узел может быть как горизонтальный так и вертикальный (опционально)

    //а последующие только вертикальные

    if(!(level_node==0&&this._arranging==arHorizontal)) node_arranging=arVertical; else node_arranging=arHorizontal;

 

    //Если данное подменю располагается вертикально, оно должно быть выведено в виде таблицы

    if(node_arranging==arVertical) Outline += "<table border='1' cellpadding='0' style='border-collapse: collapse'>";

 

    for(var i=0;i<nodes._objects_list.length;i++) {

        var div_id="_"+nodes._objects_list[i]._id+"_"+level_node;

        var class_style_name=this._get_class_style(level_node,nodes._objects_list[i]);

        var rule=_find_style_as_name("."+class_style_name);

        if(rule==null) alert("Ошибка времени выполнения стиль "+class_style_name+" не задан")

 

        //Определяем размер текста, что бы вычислить ширину меню

        var str=rule.style.fontSize;

        ms=str.slice(str.length-2,str.length);

        var size=0;

        if(ms.toLowerCase()!="pt") {

            alert("Ошибка времени выполнения: размер шрифта должен быть задан в pt");

        } else {

            size=str.slice(0,str.length-2);

        }

 

        Outline += "<A HREF='javascript:_global_container._";

        Outline += this._id+"._on_node_click("+nodes._objects_list[i]._id+","+level_node+")' ";

        Outline += "ONMOUSEOVER='_global_container._"+this._id;

        Outline += "._on_mouse_over("+nodes._objects_list[i]._id+","+level_node+","+totlen+","+i+")' ";

        Outline += "ONMOUSEOUT='_global_container._"+this._id;

        Outline += "._on_mouse_out("+nodes._objects_list[i]._id+","+level_node+")' ";

        Outline += "id='"+div_id+"'";

        Outline += " class='"+class_style_name+"'>";

        if(!(level_node==0&&this._arranging==arHorizontal)) {

        }

        if(node_arranging==arVertical) {

            Outline += "<tr class='"+class_style_name+"' id='t"+div_id;

            Outline += "' ONMOUSEOVER=this.style.cursor='hand' ";

            Outline += "><td style='border-style: none' width="+((len_m+10)*size/2)+"pt>";

        }

        Outline += nodes._objects_list[i]._name_node;

        totlen += nodes._objects_list[i]._name_node._length();

        if(node_arranging==arVertical) {

            Outline += "</td>";

 

            //во вторую колонку выводим метку подменю, если оно есть

            Outline += "<td style='border-style: none'>";

            if(nodes._objects_list[i]._nodes!=null) Outline += "&#9658;";

            Outline += "</td></tr>";

        }

        Outline += "</A>";

    }

    if(node_arranging==arVertical) Outline += "</table>";

    return Outline;

}

 

Как работает данная функция? Сначала мы проверяем, каково местоположение меню, в зависимости от этого выбираем нужный тэг:

    //Определяем расположение текущего узла меню: 0-ой узел может быть как горизонтальный так и вертикальный (опционально)

    //а последующие только вертикальные

    if(!(level_node==0&&this._arranging==arHorizontal)) node_arranging=arVertical; else node_arranging=arHorizontal;

 

    //Если данное подменю располагается вертикально, оно должно быть выведено в виде таблицы

    if(node_arranging==arVertical) Outline += "<table border='1' cellpadding='0' style='border-collapse: collapse'>";

 

Заметим, что расположение меню (вертикальное или горизонтальное) действует только для первого узла. Далее идет только вертикальное расположение.

 

Затем в цикле формируем меню (перебирая все узлы):

    for(var i=0;i<nodes._objects_list.length;i++) {

        var div_id="_"+nodes._objects_list[i]._id+"_"+level_node;

        var class_style_name=this._get_class_style(level_node,nodes._objects_list[i]);

        var rule=_find_style_as_name("."+class_style_name);

        if(rule==null) alert("Ошибка времени выполнения стиль "+class_style_name+" не задан")

...

 

Данную процедуру мы видим линейной (без рекурсии). Спрашивается, где же выводиться подменю? Посмотрите на эту строчку:

        Outline += "._on_mouse_over("+nodes._objects_list[i]._id+","+level_node+","+totlen+","+i+")' ";

 

она вставляет в формируемый HTML код реакцию на событие подвода к пункту меню мышки. Вот как обрабатывается это событие:

function CXBrMenu_on_mouse_over(id,level_node,pos,index) {

    var tag=this._document.getElementById("_"+id+"_"+level_node);

    var tag_t=this._document.getElementById("t_"+id+"_"+level_node);

    var node=_get_node_by_id(id,this._nodes);

    tag.className="active_"+this._get_class_style(level_node,node);

    if(tag_t!=null) tag_t.className="active_"+this._get_class_style(level_node,node);

    var rule=_find_style_as_name("."+tag.className);

 

    //Очищаем тэг текущего уровня и все тэги ниже него

    var i=level_node;

    while(true) {

        t=this._document.getElementById("pn"+this._id+"_"+i);

        if(t!=null) t.innerHTML=""; else break;

        i++;

    }

 

    //Создаем или находим уже созданный рабочий тэг

    var t=this._create_div(this._id+"_"+level_node);

 

    //Если есть подменю, выводим его

    if(node._nodes!=null) {

        Outline=this._out_tree(level_node+1,node._nodes);

        t.style.position="relative";

        var str=rule.style.fontSize;

        ms=str.slice(str.length-2,str.lengt);

        var size=0;

        if(ms.toLowerCase()!="pt") {

            alert("Ошибка времени выполнения: размер шрифта должен быть задан в pt");

        } else {

            size=str.slice(0,str.length-2);

        }

 

        //Если меню и верхний узел - самый верхний

        if(level_node==0&&this._arranging==arHorizontal) {

            t.style.left=pos*size/2+"pt";

            t.style.top="1pt";

 

        //Если меню вертикальное и верхний узел - самый верхний

        } else if(level_node==0&&this._arranging==arVertical)  {

            t.style.left=size*node._owner._objects_list.length+"pt";

            t.style.top="-"+((node._owner._objects_list.length-index)*size).toString()+"pt";

 

        // Остальные случаи, тут все меню располагаются вертикально и каскадно

        } else {

 

            //Для того, что бы вычислить положения подменю, найдем тэг

            //предыдущего уровня

            t_prev=this._document.getElementById("pn"+this._id+"_"+(level_node-1).toString());

            var left_prev=t_prev.currentStyle.left.slice(0,t_prev.currentStyle.left.length-2);

            var top_prev=t_prev.currentStyle.top.slice(0,t_prev.currentStyle.top.length-2)/1;

 

            var sm=left_prev/1;

            sm=sm+node._owner._max_name_length()*size/2;

 

            t.style.left=sm.toString()+"pt";

            t.style.top="-"+((node._owner._objects_list.length-index)*size-top_prev).toString()+"pt";

        }

        t.innerHTML=Outline;

    }

    this._is_active_nodes=true;

}

 

Этот обработчик находит тэг, вычисляет расположение подменю и формирует его уже знакомым вам методом. При чем только в том случае, если выбранный пункт меню содержит подменю.

 

С уважением, Шуравин Александр, e-mail: megabax@rambler.ru, автор оставляет за собой право публиковать в рассылках ваши письма, если в письме прямо неоговорено нежелание его публиковать.

 


В избранное