iOS上的JavaScript:在touchstart上使用preventDefault而不禁用滚动

Ste*_*fan 5 javascript jquery events scroll ios

我在iOS上的UIWevView中使用JavaScript和jQuery.

我添加了一些javascript事件处理程序,允许我捕获一个触摸并保持事件,以便在有人点击img一段时间时显示一条消息:

$(document).ready(function() {

    var timeoutId = 0;
    var messageAppeared = false;

    $('img').on('touchstart', function(event) {

        event.preventDefault();
        timeoutId = setTimeout(function() {           

            /* Show message ... */
            messageAppeared = true;

        }, 1000);

    }).on('touchend touchcancel', function(event) {                                

        if (messageAppeared) {
            event.preventDefault();
        } else {
            clearTimeout(timeoutId);
        }
        messageAppeared = false;        
    });
});
Run Code Online (Sandbox Code Playgroud)

这很好地显示了消息.我添加了两个"event.preventDefault();" 用于阻止链接中的imgs来触发链接的行.

问题是:这似乎也阻止了拖动事件滚动页面正常发生,因此当他的滑动恰好在img上开始时,用户将无法滚动.

如何在不干扰滚动的情况下禁用默认链接操作?

Rob*_*ert 10

你让我走上正确的轨道Stefan,让我思考另一种方式.对于仍然对此嗤之以鼻的人来说,这是我的解决方案.

我试图让访问者水平滚动图像,而不会破坏垂直滚动.但我正在执行自定义功能并等待垂直滚动发生.相反,我们应该首先允许常规行为并等待Stefan所做的特定手势.

例如:

$("img").on("touchstart", function(e) {
    var touchStart = touchEnd = e.originalEvent.touches[0].pageX;

    var touchExceeded = false;

    $(this).on("touchmove", function(e) {
        touchEnd = e.originalEvent.touches[0].pageX;

        if(touchExceeded || touchStart - touchEnd > 50 || touchEnd - touchStart > 50) {
            e.preventDefault();

            touchExceeded = true;

            // Execute your custom function.
        }
    });

    $(this).on("touchend", function(e) {
        $(this).off("touchmove touchend");
    });
});
Run Code Online (Sandbox Code Playgroud)

所以基本上我们允许默认行为,直到水平移动超过50像素.

touchExceeded如果我们重新进入初始<50像素区域,变量确保我们的函数仍然运行.

(注意这是示例代码,e.originalEvent.touches[0].pageX不兼容跨浏览器.)


Ste*_*fan 7

有时您必须在堆栈溢出问题上提出问题,以便自己找到答案.我的问题确实有一个解决方案,如下:

$(document).ready(function() {

    var timeoutId = 0;

    $('img').on('touchstart', function(event) {

        var imgElement = this;

        timeoutId = setTimeout(function() {           

            $(imgElement).one('click', function(event) {
                event.preventDefault();
            });

            /* Show message ... */

        }, 1000);

    }).on('touchend touchcancel', function(event) {                                
        clearTimeout(timeoutId);
    });
});
Run Code Online (Sandbox Code Playgroud)

说明

  • 触摸事件处理程序中没有preventDefault().这带回了滚动行为(当然).
  • 如果出现消息,则处理一次正常的点击事件,并阻止它的默认操作.