我有一个具有相当大的命中区域的锚点,其中还有一个选择下拉列表,在单击选择时不应激活链接。我知道这可能不是“规范”但我需要锚提供的功能(即cmd-click在新浏览器选项卡中打开)并且不知道任何其他方式。
以下是我所拥有的概要:
<a id="anchor" href="http://google.com" onclick="anchor(event)">
<div id="div">
<select id="select" onclick="select(event)">
<option>Option A</option>
<option>Option B</option>
<option>Option C</option>
</select>
</div>
</a>
这是一个小提琴,通常显示我正在尝试做的事情:
然而,这不是测试这个的好方法,因为小提琴不会让你跟踪链接,所以你永远不知道发生了什么。我建议将这个单机粘贴到浏览器中:
问题在于,每当我点击选择它就会跟随锚点。我已尝试在(现在裸)函数中使用各种stopPropagation和preventDefault,但我无法使用任何东西。显然,当你没有点击下拉列表时,我仍然希望锚点工作。
更糟糕的是,我可以让它主要用于chrome,但它在firefox中不起作用(还没有真正测试IE或其他)。它似乎在第一次点击时显示选择但是我使用的preventDefault()会破坏其他所有内容。
任何建议,即使与我所拥有的建议大不相同,但实现同样的目标,我们将不胜感激。谢谢!
答案 0 :(得分:0)
您可以将<select>
移到DOM中的<a>
之外,并使用CSS使它们重叠吗?您可以将它们放在一个相对定位的盒子中,以保持它们的分组;这是一个演示:http://jsfiddle.net/C3g6b/4/。
(原始答案:仅适用于Chrome)
您的处理程序未被调用,因为您已将JSFiddle设置为调用JavaScript onload,这意味着所有内容都包含在函数中,这意味着函数声明的范围限定为该函数,并且在全局范围内不可用。通过将JSFiddle设置为不包装JavaScript或创建如下函数来解决此问题:
window.select = function () {
完成后,e.preventDefault()
应该这样做。
我应该注意,如果您使用推荐的方法添加事件监听器addEventListener
,则不会发生此问题。
答案 1 :(得分:0)
您可以使用属性e.target
来确定事件的来源。因此,在anchor
事件处理程序中,只需针对e.target
元素检查select
,如果匹配,您就知道用户点击了选择框。那时您可以从处理程序返回false
并阻止浏览器打开链接。
<a id="anchor" href="http://google.com" onclick="return anchor(event)">
<div id="div">
<select id="select" onclick="select(event)">
<option>Option A</option>
<option>Option B</option>
<option>Option C</option>
</select>
</div>
</a>
function anchor(e) {
if (e.target == document.getElementById('select')) {
console.log('Preventing link click');
return false;
}
console.log('Allowing link click');
return true;
}
function select(e) {
}
一个例子是http://jsfiddle.net/mks_ios/8XXrt/。如果您打开Chrome或Firefox Web控制台,您将看到日志消息。
我在这里使用内联事件注册不偏离您的示例,但我建议远离它们并在JavaScript中注册所有事件。首先,您不必在event
中明确传递处理程序的返回值return
和onclick
。 (请参阅http://www.quirksmode.org/js/events_early.html上的“不要使用它”。)
此外,在这个问题中,了解事件模型以及事件如何在元素之间传播真的很有帮助。本文非常擅长解释它:http://www.quirksmode.org/js/events_order.html。