?

Log in

No account? Create an account

Javascript Context Menu

« previous entry | next entry »
авг. 4, 2005 | 01:14 pm
music: Алиса - Инок, воин и шут

Нужен был мне сабж. Только не контекстное меню на всю страницу, а на некоторые ссылки.
Поиски в инете привели меня на страницу elouai.com, где я нашел практически то, что мне нужно.

Однако, не совсем то =)

Во-первых, я хотел, чтобы меню всплывало только на некоторых ссылках, во-вторых, чтобы можно было это меню динамически параметризовать.

Если последняя фраза кажется излишне сложной, то поясню: у меня есть набор ссылок на объекты, у каждой ссылки есть object_id, т.е. ссылки выглядят так: <a href="view&object_id=1">text</a>. Я хочу сделать для всех этих ссылок контекстное меню из двух пунктов:
<a href="edit&object_id=1">text</a>
<a href="delete&object_id=1">text</a>

Естественно, что мне хочется набрать это меню только один раз, а не для каждой ссылки =)

В результате, когдя я сделал скрипт, ссылки выглядят так:
<a param_object_id=1 onmousedown="popupMenu(event, this)" href="view&object_id=1">text</a>
а шаблон меню, так:
<a param_href="edit&object_id=#object_id" onClick="hideMenu()" >text</a>
<a param_href="delete&object_id=#object_id" onClick="hideMenu()" >text</a>

т.е. те параметры, что в исходной ссылке (не обязательно ссылке, любом объекте, поддерживающем onmousedown) помечены, как param_имя_переменной, будут подставляться в шаблоне меню вместо #имя_переменной

Скрипт заточен под IE. С моделями обработки контекстного меню альтернативных браузеров я разбираться не стал, т.к. в моей задаче достаточно работы в IE.


скрипт
var ie  = document.all
var ns6 = document.getElementById&&!document.all

var isMenu  = false ;

var menuSelObj = null ;
var overpopupmenu = false;
var firstClick = 0;

function my_getElementsByTagName(el,str) {
  if (document.all){
    if (str=="*"){
      return el.all
        }
    else{
      return el.all.tags(str)
        }
    }
  else{
    return el.getElementsByTagName(str)
  }
} 


function mouseClickE(e) {
  if (firstClick > 0) {
    firstClick--;
    return false;
  }

  if( isMenu ) {
    if( overpopupmenu == false ) {
      hideMenu();
      return true;
    }
    return true ;
  }
  return false;
}

function popupMenu(e, l) {
  if (e.button != 2) return true;

  var menuSelObj = ns6 ? e.target.parentNode : event.srcElement.parentElement; 
  var div = document.getElementById('menudiv');
  var div_style = div.style;

  replaceParams(div, l);


  if (ns6) {
    div_style.left = e.clientX+document.body.scrollLeft;
    div_style.top = e.clientY+document.body.scrollTop;
  } else {

    sw = document.body.clientWidth;
    sh = document.body.clientHeight;
    x = event.clientX+document.body.scrollLeft;
    y = event.clientY+document.body.scrollTop;
    div_style.display = "";
    w = div.offsetWidth;
    h = div.offsetHeight;
    div_style.pixelLeft = x + w > sw ? x - w : x;
    div_style.pixelTop = y + h > sh ? y - h : y;       
  }

  isMenu = true;
  firstClick = 2;
  return false ;
}

function hideMenu() {
  isMenu = false ;
  overpopupmenu = false;
  document.getElementById('menudiv').style.display = "none" ;
  return true ;
}

var replace_data;

function replaceParams(div, data) {
  var a_elems = my_getElementsByTagName(div,"A");
  var findParams = /#([a-zA-Z]\w*)/g;
  replace_data = data;

  for(i = 0; i < a_elems.length; i++) {
    if (a_elems[i].getAttribute('param_href') != null) {
      a_elems[i].setAttribute('href', a_elems[i].getAttribute('param_href').replace(findParams, 
        function(str, name) {
          return replace_data.getAttribute('param_' + name);
        }
      )); 
    }
  }  
}

function ContextMenuStub(e) {
  if (firstClick > 0) {
    firstClick = 0;
    return false;
  } else {
    return true;
  }
}

function menuOver(td) {
  td.className = 'menu_sel';
}

function menuOut(td) {
  td.className = 'menu_unsel';
}

document.onmousedown = mouseClickE;
document.oncontextmenu = ContextMenuStub;


пример меню
<div id="menudiv" style="position:absolute;display:none;top:0px;left:0px;z-index:10000;"
onmouseover="javascript:overpopupmenu=true;" onmouseout="javascript:overpopupmenu=false;">
<a param_href="edit&object_id=#object_id" onClick="hideMenu()" >text</a><br>
<a param_href="delete&object_id=#object_id" onClick="hideMenu()" >text</a>
</div>


пример исползования меню
<a param_object_id=1 onmousedown="popupMenu(event, this)" href="view&object_id=1">text</a>

Ссылка | Оставить комментарий | Поделиться

Comments {0}