在jQuery中,是否可以防止在mousedown和mouseup事件刚刚触发后,再次执行同一元素上的单击(click)事件。
欢迎提供任何帮助或示例。
在jQuery中,是否可以防止在mousedown和mouseup事件刚刚触发后,再次执行同一元素上的单击(click)事件。
欢迎提供任何帮助或示例。
有一种笨拙的方法是在鼠标按下时禁用按钮,然后在短时间内(如100ms)后启用它。如果mouseup事件发生在此期间,将不会触发click事件。
$('#btn').on('click', function() {
alert('clicked')
});
$('#btn').on('mousedown', function() {
var btn = $(this);
btn.attr('disabled', 'disabled');
setTimeout(function() { btn.removeAttr('disabled'); }, 100);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<button id='btn'>Click me</button>
</body>
似乎还没有人以优雅的方式回答这个问题,所以我想分享我在NewbeDev (来源:https://newbedev.com/cancel-click-event-in-the-mouseup-event-handler)找到的解决方案。
答案是使用捕获阶段,在事件在您的元素上触发之前,所有父级都会在称为“捕获阶段”的过程中接收它。然后在此之后,事件将传递到您的元素,其后跟随其父级在称为“冒泡阶段”的过程中。
这里的解决方案就是在捕获阶段顶端取消事件,因此它永远不会进入您的元素进行冒泡阶段。
我的用例是滑块,因此我使用的代码类似于:
slider.addEventListener('mousedown', ev => {
// we start sliding (details omitted)
function captureClick(e) {
// we cancel the event and stop it from going further.
// preventDefault() on its own should be enough for most cases
// Your handler can also check e.defaultPrevented to know if preventDefault() was called
e.preventDefault();
// e.stopPropagation();
}
window.addEventListener('click', captureClick, true);
document.addEventListener('mouseup', e => {
// cleanup - we wait an extra frame to remove our capture
// in case the click event is delayed
requestAnimationFrame(() => {
window.removeEventListener('click', captureClick, true);
});
});
});
const COORDS = {
xDown: null,
xUp: null
}
const handleOnMouseDown = e => {
e.preventDefault()
COORDS.xUp = null
COORDS.xDown = e.clientX
}
const handleMouseUp = e => {
e.preventDefault()
COORDS.xUp = e.clientX
}
const handleOnClick = e => {
if (COORDS.xDown !== COORDS.xUp) {
e.preventDefault()
console.log('drag')
} else {
console.log('click')
}
}
const el = document.getElementById('test')
el.addEventListener('mousedown', handleOnMouseDown)
el.addEventListener('mouseup', handleMouseUp)
el.addEventListener('click', handleOnClick)
#test {
padding: 20px;
display: block;
background: #ccc
}
<a href="#" id="test">Link</a>
是的,如果在mouseup处理程序中使用return false;
,应该是可能的,因为onclick在mousedown和mouseup发生后触发。这在常规javascript中是可行的,所以它也应该适用于jquery事件处理程序。
编辑:
从事件处理程序返回一个布尔值实际上应该足以消耗事件。但是,由于这在浏览器之间非常不稳定,您应该使用函数手动取消事件冒泡:
event.stopPropagation();
其中,event 是您的事件处理程序接收的参数。
event.stopPropagation()
吗?另外:从事件处理程序返回false
是JavaScript标准中定义的方法,即使不是所有浏览器供应商都遵守这个标准。不要因为所提出的解决方案中的一个没有为您工作而对答案进行投票。 - chucktator
mousedown
后跟着mouseup
就是一次点击,如果只想让点击生效一次,可以使用one()
方法。 - adeneo