【问题标题】:Treat short swipe as click将短扫视为点击
【发布时间】:2018-01-23 22:15:27
【问题描述】:

我有一个移动网络应用程序,它在按钮等上使用了很多 click 事件处理程序。如果用户真的“点击”(即“touchdown-touchup”)按钮,所有这些都可以正常工作。但是,如果用户进行短扫,则不会触发 click 事件。这导致我的用户抱怨该应用没有记录点击/点击,并且其他应用正常运行。

当然,我可以在ontouchstartontouchend 中获取触摸坐标并计算距离 - 但我还需要知道该距离是否低于浏览器将视为“点击”的最大值。我确实想切换到使用 touchstart/touchend 事件而不是点击。

过去我使用 fastclick.js 库来处理点击/点击,但现在使用带有 touch-action: manipulation 的原生“点击”事件。有没有办法指定/控制手指在仍然注册为“点击”的按钮上的最大移动?

更新基于 cmets。该应用程序非常大,其中有数百甚至数千个事件处理程序分配(该应用程序已在过去 8 年中开发)。更改所有这些是不切实际的,因此我正在寻找一种解决方案,它允许我在全局范围内设置一次阈值或使用类似全局的 touchstart/touchend 处理程序来解决问题。

【问题讨论】:

  • 既然您知道距离和增量,为什么不直接定义自己的阈值?
  • @mad.meesh 我想你错过了我的部分问题:如何定义这个阈值?
  • 哦......你没这么说,但在这种情况下你只需做const threshold=some_val,然后检查你的距离,如果为真,然后调用点击处理程序
  • 没那么简单,因为我只需要在阈值高于标准点击阈值时调用点击处理程序,否则点击会发生两次。
  • hmm.. 然后我会定义一个 cooldownlastClicked 和/或一个 boolhasClicked 来控制你的点击率

标签: javascript events touch swipe dom-events


【解决方案1】:

我认为这是一个有趣的问题,所以我尝试为您解决它。在某种程度上,它有点类似于在dblclick 发生时阻止click 事件的问题。

至少对我来说,使用“短滑动”的距离阈值似乎是有问题的,因为阈值距离可能取决于系统。相反,我决定触发“点击”事件是否真的发生。我使用mousedown 作为模拟touchstartmouseup 作为模拟touchendmouseup 总是发生在click 之前,所以在这方面它类似于touchend

通常,如果您“单击”(mousedown) 元素,然后将鼠标指针移离该元素,则不会发生 click 事件。这很像您描述为“短刷”的情况。在一定距离之后,click 事件就不会发生。下面的代码将为该按钮发送一个click 事件,即使您将鼠标按下,然后将指针移开然后鼠标向上。我相信如果您将它用于touchstarttouchend,这将解决问题

// 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>

【讨论】:

    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    相关资源
    最近更新 更多