火狐浏览器中,<button>元素内的<span>元素缺失点击事件

28

我在Firefox 32上遇到了问题,当我将点击事件绑定到按钮元素内部的span元素时。其他浏览器似乎都可以正常工作。

这里是在jsFiddle上说明问题的代码

<span onClick="alert('test');">**Working**</span><br>
<button>inside a button <span onClick="alert('test');">**Not working**</span></button>

有人知道这是为什么吗?是一个bug还是一个特性?


1
很有趣,因为它在 Chrome 上工作得很好。但据说在 IE 上也不能工作,所以大多数情况下它不起作用。 - chowey
5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
46
你需要在 span 元素中添加 pointer-events 属性。
button span {
  pointer-events: none;
}

在我的 Firefox 66 上可以工作。有关讨论,请参见 https://css-tricks.com/slightly-careful-sub-elements-clickable-things/。 - Brian Burns
1
这应该是被接受的答案。它甚至在Chrome上也能工作。(在2022年) - Sam

31
据我所知,由于嵌套在按钮中,因此单击子元素是不起作用的。 按钮不是子元素的容器,只能包含文本。如果您尝试以下操作,则始终会告诉您单击了按钮。

<button type="button" onclick="alert('You clicked the button!');">
   inside a button <span onClick="alert('clicked span');">**Not working**</span>
</button>

所以,我的建议是使用另一个

<div class="button_replace">
  inside a div <span onClick="alert('clicked span');">**working**</span>
</div>

希望这能帮到你...

注意:你的代码可以在Chrome中运行,但无法在Firefox中运行,我的答案提供了在Firefox中运行的其他解决方案。


它正在工作,谢谢!我必须修补一个外部库来完成它,我更喜欢避免这样做,但没关系。 - Jrmi
你使用了哪个外部库?我这里也遇到了同样的问题,不得不在按钮内部使用按钮,实际上是md-button。 - Aishwat Singh
它解决了我的问题。用 div 替换按钮可以解决这个问题。谢谢! - shaosh

6
在CSS中给您的按钮添加指针事件,例如:

pointer-events:

button span {
    pointer-events: none;
}


3

在按钮内部工作
不起作用

你真正想要做的是在按钮上添加一个点击事件 - 总是按钮,因为它是原生HTML元素,并具有所有内置的无障碍功能。

如果您在包装在按钮内部的span(或等)中单击某些内容,则您的按钮单击不会触发,因为您正在监听event.target(实际单击的内容),而不是event.currentTarget。

如果您想要侦听按钮本身的点击(包括跨度在内的按钮内任何位置的点击),则可以使用以下代码:

HTML:

<button type="button" class="jsAlertOnClick">
  Inside a button 
  <span onClick="alert('Span Clicked, and...');">I'm in a span</span>
</button>

Javascript:

const myButton = document.querySelector('.jsAlertOnClick');

function handleBtnClick(event) {
  const btn = event.currentTarget;
  window.alert(btn + 'has been clicked!');
}

myButton.addEventListener('click', handleBtnClick);
如果您点击span,那么先触发该警报,然后是按钮警报。如果您在按钮的其他位置单击,则仅触发该警报。

1

根据您在按钮内使用span的原因,您可能完全可以将其去除。我曾经处理过类似的问题,我们在按钮内使用了一个span,但该span用于容纳图标:

    <button class="btn btn-default pull-right" type="button">
              <span class="glyphicon glyphicon-refresh"></span>
    </button>

我最终发现有一种更简单且更清洁的方法 - 至少在这种情况下是这样的。只需将glyphicon类的内容放在按钮类中:

    <button class="btn btn-default pull-right glyphicon glyphicon-refresh" type="button">
    </button>

问题在于span捕获事件后没有将其传递给父级。您需要在span处理完事件后传递事件。 - Dawid Wekwejt
1
@DawidWekwejt - 当然,你是对的。我的意思是,如果你在按钮内部放置一个span元素只是为了容纳一个glyphicon图标,那么你可以完全删除这个span元素,并将glyphicon图标直接放在按钮内部。这样,你就不必担心在span元素上设置事件处理程序等问题。 - harpchil
没错,你的方法更简单明了。 - Dawid Wekwejt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,