我的页面上有一个非常基本的Bootstrap按钮。我有一个事件侦听器侦听此按钮上的单击。我有一个图像标签作为按钮的内容。当用户单击该按钮时,事件侦听器将按需要触发。但是,如果按钮单击落在按钮中的图像上,则图像会拦截单击,并且按钮单击事件侦听器不会触发。我怎样才能让按钮检测到点击本身,以及它的内容(例如图像标签)?
<button type="button" class="btn btn-custom" id="navLogoButtonLeft">
<!-- dev tools indicate clicks land on this <img> and never make it to the <button> -->
<img class="icon" src="img/icon.png">
</button>
注意,这是一个Twitter Bootstrap按钮,但我不确定这对问题有任何影响。
这是JS,根据请求。
var navLogoButtonLeft;
function initNav() {
navLogoButtonLeft = document.getElementById('navLogoButtonLeft');
// note, I've tried both 'true' and 'false' here
navLogoButtonLeft.addEventListener('click', handleClick, true);
}
// this method does fire, but clickEvent is the <img>, not the <button>
function handleClick(clickEvent) {
if(clickEvent.target == navLogoButtonLeft) {
// this line cannot be reached
window.location = './';
return;
}
}
window.addEventListener('load', initNav, false);
您的开发工具是正确的。当你点击按钮中的图像时,事件目标实际上就是图像。尽管如此,click事件应该弹出并最终使按钮的事件侦听器触发。
因此,如果您的HTML是正确的(例如//
注释会破坏它),并且您正确地添加了事件侦听器,如
var btn = document.querySelector('#navLogoButtonRight');
btn.addEventListener('click', function (ev) {
ev.stopPropagation();
console.log('Event listener for element ' + ev.currentTarget.nodeName + '#' + ev.currentTarget.id + ' fired.');
console.log('Clicked on ' + ev.target.nodeName);
});
事件侦听器应该在单击按钮及其任何子元素时触发。处理程序中的ev.stopPropagation();
阻止事件进一步冒泡。这里有一个工作示例:https://jsfiddle.net/quj56hq5/
如果你必须设置pointer-events: none;
为这个工作,肯定有一些错误与你的代码或一些Twitter Bootstrap JS得到的方式。
问题作者添加JS后,问题的真正原因就显示出来了。它是
行if(clickEvent.target == navLogoButtonLeft) {
使处理程序的代码在图像被单击时不被执行,因为.target
总是被单击的元素,而.currentTarget
总是侦听器最初附加到的元素。
您可以将相同的事件侦听器添加到图像标记中以获得所需的效果。
虽然你也可以去更技术性的层面然后在CSS中添加一个设置pointer-events: none;
的类,并将该类添加到img标签的末尾
尝试反向操作(并使用气泡效果),然后尝试将侦听器应用于img(在我的示例中,我只是更改了与侦听器关联的id的位置)
<button type="button" class="btn btn-custom" >
// dev tools indicate clicks land on this <img> and never make
// it to the <button>
<img class="icon" src="img/icon.png" id="navLogoButtonRight" >
</button>