在这种情况下,不确定在哪里使用stopPropagation或preventDefault(或两者)?

时间:2014-06-01 23:17:17

标签: javascript html css dom

我有一个具有相当大的命中区域的锚点,其中还有一个选择下拉列表,在单击选择时不应激活链接。我知道这可能不是“规范”但我需要锚提供的功能(即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>

这是一个小提琴,通常显示我正在尝试做的事情:

http://jsfiddle.net/C3g6b/

然而,这不是测试这个的好方法,因为小提琴不会让你跟踪链接,所以你永远不知道发生了什么。我建议将这个单机粘贴到浏览器中:

http://pastebin.com/cvSBFAM8

问题在于,每当我点击选择它就会跟随锚点。我已尝试在(现在裸)函数中使用各种stopPropagation和preventDefault,但我无法使用任何东西。显然,当你没有点击下拉列表时,我仍然希望锚点工作。

更糟糕的是,我可以让它主要用于chrome,但它在firefox中不起作用(还没有真正测试IE或其他)。它似乎在第一次点击时显示选择但是我使用的preventDefault()会破坏其他所有内容。

任何建议,即使与我所拥有的建议大不相同,但实现同样的目标,我们将不胜感激。谢谢!

2 个答案:

答案 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中明确传递处理程序的返回值returnonclick。 (请参阅http://www.quirksmode.org/js/events_early.html上的“不要使用它”。)

此外,在这个问题中,了解事件模型以及事件如何在元素之间传播真的很有帮助。本文非常擅长解释它:http://www.quirksmode.org/js/events_order.html