javascript - 如何挂接到浏览器的上下文菜单事件

标签 javascript list contextmenu

我一直感到困惑,找不到适合我的上下文菜单。也许有人可以提供帮助?

这是我需要将 contextMenu 添加到的内容:

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

这是动态列表,因此它会在页面上添加更多列表并通过提供不同的 ID 来区分它们。所以我需要一个 contextMenu,它将被添加到每个列表中,但对于每个列表都有一个唯一的 contextMenu。通过将动态 {id} 标记添加到 contextMenu 的 ID 或类似的东西,每个列表中的 contextMenu 基本上是不同的实例。

谢谢

最佳答案

很难说出你在问什么,但如果你想 Hook 浏览器的“上下文菜单”事件,你可以 Hook contextmenu 事件,然后做任何你想做的事我们将要做的(这可能包括创建一个 div,例如,上面有选项——例如,您自己的上下文菜单)。您可以按照您在问题中指出的那样,通过 getElementById 在列表本身上单独执行此操作,或者您可以通过将事件挂接到包含所有列表的某个容器上,然后计算当事件被触发时输出它是在哪个列表上触发的(“事件委托(delegate)”)。

有关事件委托(delegate)方法,请参阅此答案的末尾。但假设您有办法知道实际使用的 ID,并且出于某种原因想要专门 Hook 每个列表:

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;
  }
}

Live example

请注意,只有部分(大多数)浏览器允许您取消默认上下文菜单。


更新:关于您的“但是如果 ID 是可绑定(bind)的怎么办?”下面的问题:恐怕我不知道你所说的“可绑定(bind)”是什么意思——你问题上的标签都没有表示特定的模板技术。您甚至没有提到模板是发生在服务器端还是客户端,这使得很难提供帮助。但基本上,在 JavaScript 运行时,文档中的真实元素上会有真实的 ID。您必须知道这些 ID 是什么才能使用 getElementById

服务器端模板:

如果这些 ID 将是完全动态的并且模板在服务器上处理,您可以包含一小段脚本,将这些 ID 传递给 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 并在连接处理程序时使用每个 ID。

客户端模板:

如果模板是在客户端完成的,这会更简单一些:只需在客户端脚本中某个方便的地方设置您的 mySpecialListIDs 列表,然后每次都附加到它你调用模板引擎。


事件委托(delegate):无论您是在做服务器端还是客户端模板,如果您要拥有这样的动态列表,有时事件委托(delegate)就是处理它的最佳方法。 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;
  }
}

Live example

关于javascript - 如何挂接到浏览器的上下文菜单事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4419392/

相关文章:

python - 让python迭代器倒退?

c++ - 如何在 c++/QT 中以编程方式右键单击文件/文件夹时添加自定义菜单?

javascript - 在 TypeScript 中使用点表示法和函数组件

javascript - 限制 jQueryUI 拖动到元素,但允许从一个元素移动到另一个元素?

javascript - 切换回来时,Jquery 切换不起作用

javascript - 如何使用一个 forEach 循环来迭代两个不同的数组?

generics - 如何在Scala中迭代列表列表?

java - 当我在 Java 中只有一个对象的引用时,如何将一个对象分配给另一个对象?

android - Android 7 中的 ContextMenu 位置困惑

Android:单击上下文菜单