Webkit <button onclick>在某些情况下无法触发

5
我发现在Webkit中,<button>元素在鼠标在点击期间从/到其子元素时不会触发onclick事件。换句话说,当mousedownmouseup事件不发生在同一个元素上时,即使两者都是按钮的子元素,也会发生这种情况。
点击/释放按钮文本的像素时也会出现相同的情况。
为了澄清,我创建了一个testcasehttp://jsfiddle.net/gx9B3/ 它在FireFox中运行良好。在Chrome 15和QtWebkit 4.7.1中失败。
有没有办法解决这个问题?我需要一个特别针对Webkit的解决方案,因为我的项目仅针对该浏览器。
解决方案:
我可以根据Jan Kuča建议的方法解决这个问题(我接受的解决方案)。还需要一些其他调整,特别是引入定时器以避免双击。请查看我在JSFiddle上完全可用的解决方案:http://jsfiddle.net/mwFQq/

你很幸运能够参与一个只针对WebKit的项目。 - Alex Turpin
1
哇,那真是奇怪。以前从没注意到过。 - OptimusCrime
这是一个在WebKit中的bug,最近似乎已经在Blink(用于Chrome)中修复了,虽然我还没有看到:https://bugs.webkit.org/show_bug.cgi?id=39620 - jackocnr
3个回答

4
你可以在 document.body 上设置一个 mousedown 监听器(以解决整个页面上的问题)。你需要检查 mousedown 事件是否来自 HTMLButtonElement(或其任何子元素),如果是,则设置一个 mouseup 监听器(在按钮上,这样就不必冒泡太多),并检查 mouseup 事件的 target 属性 。 如果它包含在按钮中且与 mousedown 事件的 target 不同,则触发 click 事件,如下所示:
var e = document.createEvent('Events');
e.initEvent('click', true, true);
button.dispatchEvent(e);

只针对基于WebKit的浏览器执行此操作,以免在其他浏览器中触发多次点击事件。或者您可以调用mousedown事件的preventDefault方法,因为它也应该防止触发click事件。


你也可以尝试在mousedown监听器中返回false。如果这不起作用,你可能需要使用浏览器检测,例如/webkit/i.test(navigator.userAgent) - J. K.
现在我想到了,你不仅会阻止click事件的触发,还会阻止mouseup事件的触发。因此,我现在想不出比浏览器检测更好的解决方案了。 - J. K.
嘿,我看到你没有正确实现我的逻辑。clickBtn && clickBtn === btn 不是正确的检查方式。我会检查 clickBtn && btn && mousedown_event.target !== mouseup_event.target - J. K.
我认为即使是纯文本按钮,也应该有可能检查它。然而,这并不适合作为评论。我将写一篇关于此的小博客文章。我想到了一个使用客户端矩形和计算样式的按钮解决方案。 - J. K.
仍然在今天使用QtWebKit 5.3发生。解决方法有效。 - Warren Seine
显示剩余5条评论

0
您可以尝试添加以下CSS样式:
button * {
    pointer-events: none;
}

子元素将忽略鼠标事件,点击将来自于按钮元素本身。这是一个例子 http://jsfiddle.net/Tetaxa/gx9B3/2/


哦,你是说QtWebKit。我自己没有那个,所以无法测试。 - Tetaxa
请尝试使用Chrome 15(我的版本是15.0.874.106,应该是最新的版本)。 - Udo G
抱歉,这确实对于带有图像的按钮有帮助,但对于纯文本按钮则没有。 - Udo G
你是对的,我一定是把指针移动到了侧边,但仍然停留在文本边界框内。这可能应该被报告为 WebKit 的一个 bug。 - Tetaxa
发现一个已经存在的错误报告:https://bugs.webkit.org/show_bug.cgi?id=39620 - Udo G

0

你也可以通过纯CSS技巧来解决它。只需在<button>上放置伪元素以覆盖文本:

button {
    position:relative;
    }
button:after {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    content:'';
    }

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