【问题标题】:Mobile Safari: Disable scrolling pages "out of screen"移动 Safari:禁用“屏幕外”滚动页面
【发布时间】:2011-10-31 00:54:08
【问题描述】:

我想阻止滚动页面“超出 iPhone 屏幕”(当页面边框后面的灰色 Safari 背景可见时)。为此,我正在取消 touchmove 事件:

// Disables scrolling the page out of the screen.
function DisableTouchScrolling()
{
    document.addEventListener("touchmove", function TouchHandler(e) { e.preventDefault(); }, true);
}

不幸的是,这也禁用了 mousemove 事件:当我点击一个按钮然后将手指移出它,然后释放屏幕时,无论如何都会触发按钮的 onclick 事件。

我尝试将触摸事件映射到鼠标事件上,如下所述:http://ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript/,但无济于事(相同的行为)。

有什么想法吗?

【问题讨论】:

    标签: iphone touch mobile-safari


    【解决方案1】:

    根据我对您的问题的了解,您已尝试将上面提供的代码与the code snippet provided by Ross Boucher on Posterous 结合起来。尝试将这两个 sn-ps 背靠背组合是行不通的,因为在禁用 touchmove 时,您还禁用了允许 mousemove 通过他的示例工作的 shim。

    This question and its answers 为您的问题制定一个可行的解决方案。你应该试试这两个 sn-ps 看看它们是否能解决你的问题:

    This snippet, 禁用旧的滚动行为:

    elementYouWantToScroll.ontouchmove = function(e) {
        e.stopPropagation();
    }; 
    

    或者这个,来自the same

    document.ontouchmove = function(e) {
        var target = e.currentTarget;
        while(target) {
            if(checkIfElementShouldScroll(target))
                return;
            target = target.parentNode;
        }
    
        e.preventDefault();
    };
    

    然后,加入the code on Posterous

    function touchHandler(event)
    {
        var touches = event.changedTouches,
            first = touches[0],
            type = "";
             switch(event.type)
        {
            case "touchstart": type = "mousedown"; break;
            case "touchmove":  type="mousemove"; break;        
            case "touchend":   type="mouseup"; break;
            default: return;
        }
    
                 //initMouseEvent(type, canBubble, cancelable, view, clickCount, 
        //           screenX, screenY, clientX, clientY, ctrlKey, 
        //           altKey, shiftKey, metaKey, button, relatedTarget);
    
        var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                                  first.screenX, first.screenY, 
                                  first.clientX, first.clientY, false, 
                                  false, false, false, 0/*left*/, null);
    
                                                                                     first.target.dispatchEvent(simulatedEvent);
        event.preventDefault();
    }
    

    这应该为你做。如果没有,则其他内容无法与 Mobile Safari 一起使用。

    【讨论】:

    • touchHandler 是如何连接的?
    【解决方案2】:

    不幸的是,我还没有时间查看上面的内容,但正在处理一个相同的问题,发现 DOM 中元素的嵌套以及您将其应用到的关系对处理程序有很大影响(猜想上面也解决了这个问题 - 'var target = e.currentTarget')。

    我使用了一种稍微不同的方法(我希望得到反馈),基本上是使用一个“锁定”类,我分配给每个元素(包括它的所有子元素)我不希望网站在有人触摸移动时滚动就可以了。

    例如在 HTML 中:

    <header class="locked">...</header>
    <div id="content">...</div>
    <footer class="locked"></div>
    

    然后我在该类上运行了一个事件侦听器(请原谅我的懒惰 jquery-selector):

    $('.ubq_locked').on('touchmove', function(e) {
      e.preventDefault();
    });
    

    这在 iO 和 Android 上对我来说效果很好,至少让我可以控制不将侦听器附加到我知道会导致问题的元素。顺便说一下,您确实需要注意您的 z-index 值。

    另外,如果它是触摸设备,我只会附加监听器,例如像这样:

    function has_touch() {
      var isTouchPad = (/hp-tablet/gi).test(navigator.appVersion);
      return 'ontouchstart' in window && !isTouchPad;
    }
    

    这样非触控设备不会受到影响。

    如果您不想向 HTML 发送垃圾邮件,您当然可以将选择器写入一个数组并运行那些 ontouchmove,但我希望在性能方面成本更高(尽管我的知识有限)。希望这能有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多