Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> секреты контекстного меню, Блокировать стандарт, показать в точке 
V
    Опции темы
Leshak
Дата 25.8.2009, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 143
Регистрация: 19.10.2005

Репутация: нет
Всего: нет



изучая JavaScript, JSON, jQuery, Ajax 
под свои потребности сделал вот этакий скрипт для меню
http://www.walks.ru/temp/del/test_menu.html
Стояли такие задачи:
- подгружать содержание и структуру через JSON
- иметь компактный и легко подстраиваемый под требуемое оформление вид

Код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
    <meta http-equiv="content-type" content="text/html; charset=windows-1251">
    <title> Test..menu...</title>
<style>
.bttn_brd { /* кнопки вызова  */
    border: solid 2px #333333;
    background-color: #ffffff;
    cursor: pointer; cursor: hand;
    color: #222222;
    font:13px/0.8 arial,helvetica,clean,sans-serif;
    font-weight: bold;
    margin: 3px;    padding: 3px;  
}

.mn { /* поле меню */
    border: solid 2px #333355;
    color: #222244;
    font:13px/1.8 arial,helvetica,clean,sans-serif;
    font-weight: bold;
    margin: 3px;    padding: 7px;  
    position: absolute;    left: 111px;    top: 33px;  
}

.mnp { /* строки меню */
    cursor: pointer; cursor: hand;
    color: #222299;
    font-weight: bold;
}
.mnh { /* строка возврата на предыдущее меню / закрытие */
    cursor: pointer; cursor: hand;
    color: #999999;
    font-weight: bold;
}

#p0{ position: absolute;    left: 222px;    top: 2px; }
#p1{ position: absolute;    left: 373px;    top: 2px; }
#p2{ position: absolute;    left: 555px;    top: 2px; }
#p3{ position: absolute;    left: 357px;    top: 252px; }
#p0, #p1, #p2, #p3 { background-color: #ffffff; }

</style>

<script type="text/javascript" src="http://www.walks.ru/stdt/templ/jquery-1.3.2.min.js"></script>

    
<script language="JavaScript">
var browserName = navigator.appName;
var widthScrn; 
var heightScrn;

function doShow(){ screenSize(); }

function screenSize() {
    widthScrn = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth ;
    heightScrn = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight ;
} 

 // Функция для определения координат указателя мыши
function defPosition(event) {
      var x = y = 0;
      if (document.attachEvent != null) { // Internet Explorer & Opera
            x = window.event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
            y = window.event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
      } else if (!document.attachEvent && document.addEventListener) { // Gecko
            x = event.clientX + window.scrollX;
            y = event.clientY + window.scrollY;
      } else {
            // Do nothing
      }
//      test.innerHTML ='[ x='+x+'] [ y='+y+']<br>' ;
      return {x:x, y:y};
}

var mN = new Object();
var mNp= new Object();
var M = new Object();
//  структура хэша: дерево меню задается сочетанием элементов vol и именем следующей панели
//  в nam - название пункта меню,  в ex - функция вызываемая на конце ветки меню
    M ={
        "style":{"backgroundColor":"#f9f9f9"},
        "pR":[    
                {"nam":"правая кнопка 1r","vol":"p_1r","ex":"alert('ex p_1r')"},
                {"nam":"правая кнопка 2r","vol":"p_2r"},
                {"nam":"правая кнопка 3r","vol":"p_3r","ex":"alert('ex p_3r')"},    
                {"nam":"правая кнопка 4r","vol":"p_4r","ex":"alert('ex p_3r')"}    
        ],
        "p_2r":[    
                {"nam":"правая кнопка 12r","vol":"p_12r","ex":"alert('ex p_12r')"},
                {"nam":"правая кнопка 22r","vol":"p_22r","ex":"alert('ex p_22r')"}
        ],
        "p_3":[    
                {"nam":"в полете 13","vol":"p_13","ex":"alert('ex p_13')"},
                {"nam":"в полете 23","vol":"p_23","ex":"alert('ex p_23')"},
                {"nam":"в полете 33","vol":"p_33","ex":"alert('ex p_33')"}    
        ],
        "p_0":[    
                {"nam":"начало 10","vol":"p_10"},
                {"nam":"начало 20","vol":"p_20"},
                {"nam":"начало 30","vol":"p_30","ex":"alert('ex p_30')"}    
        ],
        "p_10":[    
                {"nam":"начало 110","vol":"p_110","ex":"alert('ex p_110')"},
                {"nam":"начало 210","vol":"p_210","ex":"alert('ex p_210')"},
                {"nam":"начало 310","vol":"p_310","ex":"alert('ex p_310')"}    
        ],
        "p_20":[    
                {"nam":"начало 120","vol":"p_120","ex":"alert('ex p_120')"},
                {"nam":"начало 220","vol":"p_220","ex":"alert('ex p_220')"},
                {"nam":"начало 320","vol":"p_320","ex":"alert('ex p_320')"}    
        ],
        "p_1":[    
                {"nam":"продолжение 11","vol":"p_11"},
                {"nam":"продолжение 21","vol":"p_21"},
                {"nam":"продолжение 31","vol":"p_31"}    
        ],
        "p_2":[    
                {"nam":"окончание 12","vol":"p_12","ex":"alert('ex p_12')"},
                {"nam":"окончание 22","vol":"p_22","ex":"alert('ex p_22')"},
                {"nam":"окончание 32","vol":"p_32","ex":"alert('ex p_32')"}    
        ],
        "p_11":[    
                {"nam":"продолжение 111","vol":"p_111","ex":"alert('ex p_111')"},
                {"nam":"продолжение 211","vol":"p_211","ex":"alert('ex p_211')"},
                {"nam":"продолжение 311","vol":"p_311","ex":"alert('ex p_311')"}    
        ],
        "p_21":[    
                {"nam":"продолжение 121","vol":"p_121","ex":"alert('ex p_121')"},
                {"nam":"продолжение 221","vol":"p_221"},
                {"nam":"продолжение 321","vol":"p_321","ex":"alert('ex p_321')"}    
        ],
        "p_221":[    
                {"nam":"продолжение 1221","vol":"p_1221","ex":"alert('ex p_1221')"},
                {"nam":"продолжение 2221","vol":"p_2221","ex":"alert('ex p_2221')"}
                
        ],
        "p_31":[    
                {"nam":"продолжение 131","vol":"p_131","ex":"alert('ex p_131')"},
                {"nam":"продолжение 231","vol":"p_231","ex":"alert('ex p_231')"},
                {"nam":"продолжение 331","vol":"p_331","ex":"alert('ex p_331')"}    
        ]
        
    };
    
var onovr = function(e){    // меняем рамочку элемента при приходе курсора
    document.getElementById(e).style.border = 'solid 2px #777777';
    return false;
}

var onout = function(e){    // меняем рамочку элемента при уходе курсора
    document.getElementById(e).style.border = 'solid 2px #333333';
    return false;  
}

var mnopen = function(){ menu(this.name,this.parent); } // показать пункт меню
var mnexec = function(){ eval(this.ex); mp_close(this.parent); } // выполнить пункт меню

var mnreopen = function(parent,id){    // вернулись к предыдущей   mnreopen( id, mn )
    mp_close(id); 
    if( (parent!="undefined") && (parent!=undefined) && (parent!=0) ) { menu(parent,parent); } 
}

function mp_open(id){  //  показать панельку меню
    //    document.getElementById(id).style.display = 'block' ;  // без jquery
        $('#'+id).slideDown(300) ;    // используя jquery
}
function mp_close(id){  //  убрать панельку меню
    //    document.getElementById(id).style.display = 'none' ;  // без jquery
        $('#'+id).slideUp(300) ;    // используя jquery
}

var x;
var y;
function menu(mn,id,evt){
    if( evt ) {
        evt = evt || window.event;    // Блокируем всплывание события contextmenu
        evt.cancelBubble = true;    // работает - но непонятно почему???
        x = defPosition(evt).x + 'px';    // привязываемся к координатам клика
        y = defPosition(evt).y + 'px';    // ---------//-------
    } else if( (id!="undefined") && (id!=undefined) && (id!=0) ){
        x = mN[id].style.left;    // наследуем координаты от родителя
        y = mN[id].style.top ;    // ---------//-------
    } else {
        x = (widthScrn/2-121) + 'px';    // координаты по умолчанию
        y = 44 + 'px';    // ---------//-------
    }
    //    test.innerHTML +='!!!![ x='+x+'] [ y='+y+']<br>' ;
//    tyds.innerHTML +='menu [ mn='+mn+'] [ id='+id+']<br>' ;
    if( (id!="undefined") && (id!=undefined) && (id!=0) ) {  mp_close(id); }    // закрыли предыдущую панельку
    var ret ="закрыть";        //  заголовок по умолчанию
    if ( (mNp[mn]!="undefined") && (mNp[mn]!=undefined) ) { 
        ret=mNp[mn].innerHTML;          // заголовок по умолчанию заменили на название кликнутого пункта
        if ( ret.indexOf('+') >= 0 ) { ret=ret.replace(/\+/,"-"); } //  заменили  + на -
    }
    if( typeof(mN[mn]) != "object" ) {  
        mN[mn] = document.createElement("DIV"); // создали пункт меню
        mN[mn].id = mn;
        mN[mn].parent = id;  //  вызывающий пункт меню 
        mN[mn].innerHTML = '<div class="mnh" onclick="mnreopen(\''+id+'\',\''+mn+'\')" >'+ret+'</div>';
        mN[mn].className = 'mn';    // привязали стиль оформления
        mN[mn].style.left = x;        // привязали к клику
        mN[mn].style.top = y ;        // привязали к клику
        mN[mn].style.display = 'none';    //  пока закрыли - что бы "развернуть готовый"
        if ( (M.style.backgroundColor!="undefined") && (M.style.backgroundColor!=undefined) ) { 
            mN[mn].style.backgroundColor=M.style.backgroundColor ;  // проба брать оформление из хэша
        }
        mprnt.appendChild(mN[mn]);   // приязали пункт меню  / mprnt - текущий парент меню
        var t;
        var top;
        for(i in M[mn]) {  // перебираем текущий пункт
            if( typeof(M[mn][i]) == "object" ) {  
                t = M[mn][i]['vol']; 
                mNp[t] = document.createElement("DIV");    
                mNp[t].name = t;
                mNp[t].parent = mN[mn].id; // оно же mn
                if(M[mn][i]['ex']){
                    mNp[t].ex = M[mn][i]['ex'];
                    mNp[t].onclick = mnexec;
                    top='&bull;';    // элемент оформления - исполняемый пункт
                }else{
                    mNp[t].onclick = mnopen;
                    top='+';        // элемент оформления - следующее меню
                }
                mNp[t].className= 'mnp';
                mNp[t].innerHTML +="<nobr>"+M[mn][i]['nam']+" "+top+"</nobr>";
                mN[mn].appendChild(mNp[t]);
            } else {
            alert('MenuError');
            }
        }
        mp_open(mN[mn].id);
        mN.debug;
    } else {
        mp_open(mN[mn].id);
    //    tyds.innerHTML +='--visible:: mN_mn_id ['+mN[mn].id+']  mn ['+mn+']<br>'; 
    }
     return false;  
}

</script>    
</head>
<body  onload="doShow();" onResize="screenSize();"  >    

<p id="p0" class="bttn_brd" onclick="menu('p_0',0,event);" onmouseover="onovr('p0');" onmouseout="onout('p0');" >начали</p>
<p id="p1" class="bttn_brd" onclick="menu('p_1',0,event);" onmouseover="onovr('p1');" onmouseout="onout('p1');" >продолжили</p>
<p id="p2" class="bttn_brd" onclick="menu('p_2');" onmouseover="onovr('p2');" onmouseout="onout('p2');" >закончли</p>
<p id="p3" class="bttn_brd" onclick="menu('p_3',0,event);" oncontextmenu="menu('pR',0,event);" >в полете (правая кнопка)</p>
<div id="mprnt"></div>
<b>test menu</b>
<hr>
<script language="JavaScript">
document.writeln(" ItIs <b>"+browserName+"</b>"); 
</script>
<hr>
<span id="test" ></span>
<p id="tyds" />
<script language="JavaScript">
document.writeln(" -: end :- "); 
    var tyds = document.getElementById('tyds');        //  вывод отладочной информации
    var test = document.getElementById('test');        //  вывод отладочной информации
    var mprnt = document.getElementById('mprnt');    // меню привязываются к этому элементу
      
</script>        

</body>
</html>


дошел до подключения контекстного меню - по правой кнопке мыши и уперся в 2 вопроса
1 - блокирование стандартного меню, но только при нажатии на определенном объекте
нашел пару вариантов, - вопрос снят - : но так и не понял до конца - как и почему это работает?? smile

 2 - открытие контекстного меню в точке клика - вопрос снят - : взял функцию из одного источника и разобрался со своей логикой (кажется)  smile


Это сообщение отредактировал(а) Leshak - 26.8.2009, 12:00
PM MAIL   Вверх
EmilRegis
Дата 26.8.2009, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 21.9.2007

Репутация: 1
Всего: 4



по второму вопросу - для меню position:absolute и устанавливать в стиле аттрибуты top и left в зависимости от координатов мыши
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0410 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.