我有一个移动网络应用,它在按钮等上使用了很多click
事件处理程序。如果用户确实"点击" (即" touchdown-touchup")按钮。但是,如果用户执行了短暂滑动,则click
事件不会触发。这会引起我的用户的很多抱怨,即该应用无法注册点击/点按,其他应用也能正常运行。
当然,我可以在ontouchstart
和ontouchend
中获取触摸的坐标并计算距离 - 但我还需要知道该距离是否低于浏览器将视为&的最大距离#39;单击&#39 ;.我 not 想要切换到使用touchstart / touchend事件而不是点击。
我曾经使用fastclick.js库来处理过去的点击/点击,但现在使用原生'点击' touch-action: manipulation
的事件。是否有任何方法可以指定/控制手指在按钮上的最大移动仍然可以注册为“点击”?
更新。该应用程序非常庞大,整个过程中有数百个(如果不是数千个)事件处理程序分配(该应用程序已在过去8年中开发)。改变所有这些是不切实际的,因此我正在寻找一种解决方案,允许我在全局范围内设置一次阈值或使用类似全局的touchstart / touchend处理程序解决问题。
答案 0 :(得分:1)
我认为这是一个有趣的问题,所以我为你解决了这个问题。在某种程度上,它与click
发生时阻止dblclick
事件的问题有些相似。
使用距离阈值进行"短暂滑动"至少对我来说似乎是有问题的,因为阈值距离可能与系统有关。而不是我决定触发,如果"点击"事件真的发生了。我使用mousedown
作为模拟touchstart
和mouseup
作为模拟touchend
。 mouseup
始终在click
之前发生,因此在这方面类似于touchend
。
通常,如果你"点击" (mousedown
)在元素上,然后将鼠标指针移离元素,click
事件不会发生。这很像你描述的那种短暂滑动"。在一定距离之后,click
事件才会发生。下面的代码将为按钮发送click
事件,即使你已经在它上面移动,将指针移开它然后鼠标按下。我相信如果您将其用于touchstart
和touchend
,这可以解决问题
// The pre-exisiting click handler
function handleClick(ev) {
console.log('button clicked. do work.');
}
document.getElementById('theButton').addEventListener('click', handleClick);
// our global "touch" handlers
var touchHandler = {
curPending: null,
curElem: null,
handleTouch: function handleTouch(ev) {
switch (ev.type) {
case 'mousedown':
// capture the target that the click is being initiated on
touchHandler.curElem = ev.target;
// add an extra click handler so we know if the click event happens
ev.target.addEventListener('click', touchHandler.specialClick);
break;
case 'mouseup':
// start a pending click timer in case the click event doesn't happen
touchHandler.curPending = setTimeout(touchHandler.pendingClick, 1);
break;
}
},
specialClick: function(ev) {
// the click event happened
// clear our extra handler
touchHandler.curElem.removeEventListener('click', touchHandler.specialClick);
// make sure we don't send an extra click event
clearTimeout(touchHandler.curPending);
},
pendingClick: function() {
// we never heard the click event
// clear our extra handler
touchHandler.curElem.removeEventListener('click', touchHandler.specialClick);
// trigger a click event on the element that started it all
touchHandler.curElem.click();
}
};
// using "mousedown" as "touchstart" and "mouseup" as "touchend"
document.addEventListener('mouseup', touchHandler.handleTouch);
document.addEventListener('mousedown', touchHandler.handleTouch);

<p>I work when clicked normally but I also work when
mousedown, drag pointer off me, mouseup</p>
<button id="theButton">Click Me</button>
&#13;