【问题标题】:Avoid long-tap behaviour on mobile devices while pressing a button避免在移动设备上按下按钮时长按行为
【发布时间】:2015-06-17 09:48:18
【问题描述】:

在我的 HTML 中有一个可以短按和长按的按钮。如果您很快单击它(就像在每个其他按钮上一样),它会执行给定的回调函数。当您按住按钮时,回调将重复执行,直到检测到 mouseup 或 mouseout 事件。

var onBtnClick = function (evt, callback) {
        //only react to left mouse button
        if (evt.which == 1) {
            //save 'this' context and interval/timeout IDs
            var self    = this,
                interval= null,
                timeout = null;

            //react to a single click
            callback();

            //when user leaves the button cancel timeout/interval, lose focus and unbind recently bound listeners
            self.on("mouseup mouseout", function () {
                window.clearTimeout(timeout);
                window.clearInterval(interval);
                self.blur();
                self.off("mouseup mouseout");
            });

            //on a long click call the callback function within an interval for faster value changing
            timeout = window.setTimeout(function () {
                interval = window.setInterval(callback, 50);
            }, 300);
        }
    },

    i = 0,

    cb = function () {
        console.log(i++);
    };

$("button").mousedown(function(evt) {
    onBtnClick.call($(this), evt, cb);
});

这在桌面环境中运行良好。但是:在移动设备上使用网站时,不会注册长按,因为浏览器检测到右键单击(长按)。

是否可以在移动设备上从桌面重新创建行为?我怎样才能做到这一点?

【问题讨论】:

  • 确保回调只触发一次!
  • @LShetty:但我想触发回调,只要用户按住按钮...

标签: javascript android jquery ios mobile


【解决方案1】:

您将希望为移动设备添加 touchstarttouchend 事件。此外,您需要确保为他们提供的功能包括对evt.preventDefault() 的调用。这样做有效地告诉移动浏览器“嘿,你知道你现在通常想做的事情吗?不要那样做。”

也就是说,您提供的代码的更新版本应该如下所示:

var onBtnClick = function (evt, callback) {
        //only react to left mouse button or a touch event
        if (evt.which == 1 || evt.type == "touchstart") {
            //save 'this' context and interval/timeout IDs
            var self    = this,
                interval= null,
                timeout = null;

            //react to a single click
            callback();

            //when user leaves the button cancel timeout/interval, lose focus and unbind recently bound listeners
            self.on("mouseup mouseout touchend", function (evt) {
                window.clearTimeout(timeout);
                window.clearInterval(interval);
                self.blur();
                self.off("mouseup mouseout touchend");
                evt.preventDefault();
            });

            //on a long click call the callback function within an interval for faster value changing
            timeout = window.setTimeout(function () {
                interval = window.setInterval(callback, 50);
            }, 300);
        }
    },

    i = 0,

    cb = function () {
        console.log(i++);
    };

$("button").mousedown(function(evt) {
    onBtnClick.call($(this), evt, cb);
});

$('#hold').on('touchstart', function (evt) {
    onBtnClick.call($(this), evt, cb);
    evt.preventDefault();
});

关键更改:在 if 检查中添加了|| evt.type == "touchstart",以便捕获鼠标左键和触摸事件,在mouseupmouseout 事件列表中添加了touchend,在函数中添加了evt.preventDefault()这会清除您的超时,并添加了一个 on('touchstart' jQuery 调用以确保您的按钮实际上专门监听触摸和点击。

【讨论】:

  • 就是这样。谢谢!我尝试使用evt.preventDefault(); 而不是return false;,这对我来说也很好。
  • 我实际上完全忘记了preventDefault 是一个东西。这很可能是处理它的更好方法。我会更新答案以匹配。
  • 我测试了一下,现在在带有移动 IE 的 Windows Phone 上我遇到了另一个问题。避免上下文菜单可以正常工作,但如果我一直按下按钮,回调只会被调用 12 次然后停止(就像我已经停止按下一样)。我必须再按一次才能再走 12 步,依此类推。这里有什么问题,为什么只要我按住按钮,回调就不会被调用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多