我一直感到困惑,找不到适合我的上下文菜单。也许有人可以提供帮助?
这是我需要将 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;
}
}
请注意,只有部分(大多数)浏览器允许您取消默认上下文菜单。
更新:关于您的“但是如果 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;
}
}
关于javascript - 如何挂接到浏览器的上下文菜单事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4419392/