Как подключиться к контекстному событию браузера - PullRequest
1 голос
/ 12 декабря 2010

Я все время удивляюсь, не могу найти контекстное меню, которое будет работать для меня.Может быть, кто-то может помочь?

Вот что мне нужно, чтобы contextMenu был добавлен в:

<ul id="list_{id}" class="list">
   <li id="Item_{id}"><a ondblclick=""><span>{title}</span></a></li>
</ul>

Это динамический список, поэтому он добавит еще много их на страницу и отличает ихдавая разные идентификаторы.Поэтому мне нужен contextMenu, который будет добавлен в каждый список, но для каждого списка уникальное contextMenu.В основном разные экземпляры contextMenu в каждом списке, добавляя динамический тег {id} к идентификатору contextMenu или что-то в этом роде.

Спасибо

1 Ответ

6 голосов
/ 12 декабря 2010

Трудно сказать, о чем вы спрашиваете, но если вы хотите подключиться к событию "контекстного меню" браузера, вы подключаете событие contextmenu и затем делаете все, что собираетесь сделать (что может включать создание div, например, с опциями на нем - например, ваше собственное контекстное меню).Вы можете сделать это в самих списках, по отдельности, через getElementById, как вы указали в своем вопросе, или вы можете сделать это, перехватив событие в каком-либо контейнере, который содержит все списки, и затем выяснить, когда событиетриггер, по какому списку он был запущен («делегирование события»).

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

HTML:

<ul id='list_1'>
  <li>List 1 item 1</li>
  <li>List 1 item 2</li>
</ul>
<ul id='list_2'>
  <li>List 2 item 1</li>
  <li>List 2 item 2</li>
</ul>

JavaScript:

hookEvent(document.getElementById('list_1'), 'contextmenu', function(event) {
  event = event || window.event;
  if (event.preventDefault) {
    event.preventDefault();
  }
  display("List 1 context menu");
  return false;
});
hookEvent(document.getElementById('list_2'), 'contextmenu', function(event) {
  event = event || window.event;
  if (event.preventDefault) {
    event.preventDefault();
  }
  display("List 2 context menu");
  return false;
});

function hookEvent(element, event, handler) {
  if (element.addEventListener) {
    element.addEventListener( event, handler, false);
  }
  else if (element.attachEvent) {
    element.attachEvent('on' + event, handler);
  }
  else {
    element['on' + event] = handler;
  }
}

Пример в реальном времени

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


Обновление : Reваше "но что, если ID является привязываемым?"Вопрос ниже: боюсь, я не знаю, что вы подразумеваете под «связываемым» - ни один из тегов вашего вопроса не указывает на конкретную технологию шаблонов.Вы даже не упомянули, происходит ли создание шаблонов на стороне сервера или на стороне клиента, что затрудняет помощь.Но в основном, к тому времени, когда JavaScript будет работать, в документе будут реальные идентификаторы реальных элементов.Вы должны будете знать, что это за идентификаторы, чтобы использовать getElementById.

Серверные шаблоны :

Если эти идентификаторы будут полностью динамическимии шаблон обрабатывается на сервере, вы можете включить небольшой скрипт, который передает эти идентификаторы в JavaScript.Например, в верхней части документа вы можете иметь:

<script type='text/javascript'>
var mySpecialListIDs = [];
</script>

... и затем обновлять шаблон, добавляя небольшой тег script при каждом его расширении:

<ul id="list_{id}" class="list">
   <li id="Item_{id}"><a ondblclick=""><span>{title}</span></a></li>
</ul>
<script type='text/javascript'>
mySpecialListIDs.push("{id}");
</script>

Тогда ваш код на стороне клиента может циклически проходить через mySpecialLitIDs и использовать каждый идентификатор при подключении обработчика.

Шаблоны на стороне клиента :

Если шаблонывыполняется на стороне клиента, это становится немного проще: просто настройте список mySpecialListIDs в каком-нибудь удобном месте в скрипте на стороне клиента и добавляйте к нему каждый раз, когда вы вызываете механизм шаблонов.


Делегирование событий : Если вы используете шаблонизацию на стороне сервера или на стороне клиента, если вам нужны такие динамические списки, иногда делегирование событий является лучшимспособ справиться с этим.Событие contextmenu (как и большинство, но не все события) пузыри вверх по DOM.Таким образом, если вы подключите его к элементу-предку (что-то, что содержит все ваши списки, например, само тело документа или что-то подобное), вы можете увидеть, какой фактический список был выбран, изучив объект события.Например:

HTML:

<div id='list_container'>
  <ul id='list_1'>
    <li>List 1 item 1</li>
    <li>List 1 item 2</li>
  </ul>
  <ul id='list_2'>
    <li>List 2 item 1</li>
    <li>List 2 item 2</li>
  </ul>
</div>

JavaScript (с использованием функции hookEvent сверху):

// Hook up the contextmenu event on the container, not
// on each list:
hookEvent(document.getElementById('list_container'),
          'contextmenu',
          handleListContextMenu);

// Our handler function
function handleListContextMenu(event) {
  var target;

  // Handle IE-vs-the-world difference
  event = event || window.event;

  // Find out what the actual target element clicked was
  target = event.target || event.srcElement;

  // See if it or an ancestor of it is one of our lists
  while (target &&
         (target.tagName !== "UL" || !target.id || target.id.substring(0, 5) !== "list_")) {
    target = target.parentNode;
  }

  // Did we find a list?
  if (target) {
    // Yes, handle this.
    if (event.preventDefault) {
      event.preventDefault();
    }
    display("List '" + target.id + "' context menu");
    return false;
  }
}

Пример в реальном времени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...