JavaScript touchend versus click dilemma

我是研究僧i 提交于 2019-11-29 20:46:21
suncat100

After a day of research, I figured the best solution is to just stick to click and use https://github.com/ftlabs/fastclick to remove the touch delay. I am not 100% sure this is as efficient as touchend, but not far from at least.

I did figure out a way to disable triggering events twice on touch by using stopPropagation and preventDefault, but this is dodgy as it could interfere with other touch gestures depending on the element where it is applied:

button.on('touchend click', function(event) {
  event.stopPropagation();
  event.preventDefault();
  // this fires once on all devices
});

I was in fact looking for a solution to combine touchstart on some UI elements, but I can't see how that can be combined with click other than the solution above.

quangpdt

This question is answered but maybe needs to be updated.

According to a notice from Google, there will be no 300-350ms delay any more if we include the line below in the <head> element.

<meta name="viewport" content="width=device-width">

That's it! And there will be no difference between click and touch event anymore!

Yes disabling double-tap zoom (and hence the click delay) is usually the best option. And we finally have good advice for doing this that will soon work on all browsers.

If, for some reason, you don't want to do that. You can also use UIEvent.sourceCapabilities.firesTouchEvents to explicitly ignore the redundant click. The polyfill for this does something similar to your debouncing code.

Hello you can implement the following way.

function eventHandler(event, selector) {
    event.stopPropagation(); // Stop event bubbling.
    event.preventDefault(); // Prevent default behaviour
    if (event.type === 'touchend') selector.off('click'); // If event type was touch turn off clicks to prevent phantom clicks.
}

// Implement
$('.class').on('touchend click', function(event) {
    eventHandler(event, $(this)); // Handle the event.
    // Do somethings...
});

Your debounce function will delay handling of every click for 100 ms:

button.on('click touchend', $.debounce(100, function(event) {
  // this is delayed a minimum of 100 ms
}));

Instead, I created a cancelDuplicates function that fires right away, but any subsequent calls within 10 ms will be cancelled:

function cancelDuplicates(fn, threshhold, scope) {
    if (typeof threshhold !== 'number') threshhold = 10;
    var last = 0;

    return function () {
        var now = +new Date;

        if (now >= last + threshhold) {
            last = now;
            fn.apply(scope || this, arguments);
        }
    };
}

Usage:

button.on('click touchend', cancelDuplicates(function(event) {
  // This fires right away, and calls within 10 ms after are cancelled.
}));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!