【问题标题】:Is there a way to remove the clicking lag on mobile touch devices?有没有办法消除移动触摸设备上的点击延迟?
【发布时间】:2015-07-24 18:18:50
【问题描述】:

在移动设备(iPad、Galaxy Tab)上查看网站时,单击元素(常规链接或使用 javascript/jquery 可点击的任何其他内容)时总会出现延迟。

在线阅读时,我发现浏览器正在使用 touchstart 后跟 touchend 事件,然后触发常规点击事件。有没有办法让点击响应更快并删除延迟的点击事件?也许通过使用 javascript 或其他方式?

【问题讨论】:

    标签: android ipad mobile webkit


    【解决方案1】:

    改编自Matt的库(https://stackoverflow.com/a/9370637/1491212)本身改编自google代码,我写了一个jQuery插件。

    这样使用:$('mySelector').fastClick(handler);

    (function($){
        var clickbuster = {
            preventGhostClick: function(x, y) {
              clickbuster.coordinates.push(x, y);
              window.setTimeout(clickbuster.pop, 2500);
            },
            pop: function() {
              clickbuster.coordinates.splice(0, 2);
            },
            onClick: function(event) {
              for (var i = 0; i < clickbuster.coordinates.length; i += 2) {
                var x = clickbuster.coordinates[i];
                var y = clickbuster.coordinates[i + 1];
                if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
                  event.stopPropagation();
                  event.preventDefault();
                }
              }
            }
        };
    
    
        var methods = {
            init: function(handler){
                return this.each(function() {
                    var $this = $(this),
                        data = $this.data('fastClick');
                    if(!data){
                        this.addEventListener('touchstart', methods.handleEvent, false);
                        this.addEventListener('click', methods.handleEvent, false);
                        $this.data('fastClick', {
                            target: $this,
                            handler: handler
                        });
                    }
                });
            },
            handleEvent:function(event) {
              switch (event.type) {
                case 'touchstart': $(this).fastClick('onTouchStart',event); break;
                case 'touchmove': $(this).fastClick('onTouchMove',event); break;
                case 'touchend': $(this).fastClick('onClick',event); break;
                case 'click': $(this).fastClick('onClick',event); break;
              }
            },
            onTouchStart: function(event) {
              event.stopPropagation();
              this[0].addEventListener('touchend', methods.handleEvent, false);
              var _this = this;
              document.body.addEventListener('touchmove', function(event){
                methods.handleEvent.apply(_this,[event]);
              }, false);
    
              $(this).data('fastClick').startX = event.touches[0].clientX;
              $(this).data('fastClick').startY = event.touches[0].clientY;
            },
            onTouchMove: function(event) {
              if (Math.abs(event.touches[0].clientX - this.data('fastClick').startX) > 10 ||
                  Math.abs(event.touches[0].clientY - this.data('fastClick').startY) > 10) {
                  this.fastClick('reset');
              }
            },
            onClick: function(event) {
              event.stopPropagation();
              $(this).fastClick('reset');
              $(this).data('fastClick').handler.call(this,event);
    
              if (event.type == 'touchend') {
                clickbuster.preventGhostClick($(this).data('fastClick').startX, $(this).data('fastClick').startY);
              }
            },
            reset: function() {
              this[0].removeEventListener('touchend', methods.handleEvent, false);
              document.body.removeEventListener('touchmove', methods.handleEvent, false);
            }
        }
        $.fn.fastClick = function(method) {
            if (methods[method]) {
                return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
            } else if ( typeof method === 'object' || typeof method === 'function' || !method) {
                return methods.init.apply(this, arguments);
            } else {
                $.error('Method ' + method + ' does not exist on jQuery.hScroll');
            }
    
        }
    
        clickbuster.coordinates = [];
        document.addEventListener('click', clickbuster.onClick, true);
    
    })(jQuery);
    

    【讨论】:

    • 这似乎很酷,但我不知道如何知道我点击了什么 - $(this) 不会返回你点击的东西,这与通常绑定事件不同。 $('a').fastClick(function(){alert($(this).attr('href'))}); 例如——我怎样才能让它工作?
    • 我也遇到了这个问题。刚刚编辑了我的答案。 onClick 处理程序必须在正确的范围内调用: handler.call(this,event);见编辑
    • 另外,这还需要吗?我看到一些文章表明,从 Gingerbread 开始,如果您禁用缩放视口元标记,触摸就没有延迟……知道吗?
    • 不知道android但iOS仍然需要它
    • 在 iOS 上你不能只绑定到 touch 而不是 click - 很确定 touch 没有延迟。
    【解决方案2】:

    如果您正在编写自己的网页,您可以为 touchstart 和 touchend 注册一个侦听器,并直接从 touch end 触发 onclick 代码。

    如果您不处理触摸移动事件,浏览器将向元素调度(有一些延迟)点击事件

    看看谷歌的这个描述来创建“快速按钮”:http://code.google.com/intl/de-DE/mobile/articles/fast_buttons.html

    【讨论】:

    • 如果您能发布一些有关如何执行此操作的代码,我们将不胜感激。我通常在构建网站时使用 jQuery,我知道我可以使用 .trigger() 来触发点击事件。但我不知道如何在每次“点击”时自动调用“点击”,而无需每次需要时手动添加...
    【解决方案3】:

    如果设备支持像 Modernizer 这样的触摸,我会使用检测。我根据结果填充一个名为touchClick 的变量'click''touchend' 是否是触摸设备。在 jquery 中我只是调用:

     $('element').on(touchClick, function(e){ //do something });
    

    它的占地面积非常小。

    【讨论】:

    • 如果在支持触摸屏的笔记本电脑上使用浏览器,这种方法很危险。鼠标点击不起作用...
    猜你喜欢
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多