【问题标题】:Disable scrolling in an iPhone web application?在 iPhone Web 应用程序中禁用滚动?
【发布时间】:2011-02-22 20:07:29
【问题描述】:

有什么方法可以完全禁用 iPhone 网络应用程序中的网页滚动?我尝试了很多在 google 上发布的东西,但似乎都没有。

这是我当前的标题设置:

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>

document.body.addEventListener('touchmove', function(e){ e.preventDefault(); });

好像没用。

【问题讨论】:

  • kendall,你介意添加更多代码,这样我就可以看到里面发生了什么......我对此很陌生 - 这就是我所拥有的不起作用:&lt;script language="javascript"&gt; document.body.addEventListener('touchmove', function(e){ e.preventDefault(); }); document.body.addEventListener('touchstart', function(e){ e.preventDefault(); }); &lt;/script&gt;
  • 没关系我用过这个:document.ontouchmove = function(e){ e.preventDefault(); }

标签: javascript iphone scroll


【解决方案1】:

更改为touchstart 事件而不是touchmove。在One Finger Events 下它表示在平底锅期间没有发送任何事件,因此touchmove 可能为时已晚。

我将侦听器添加到文档,而不是正文。

示例:

document.ontouchstart = function(e){ 
    e.preventDefault(); 
}

【讨论】:

  • 您实际上需要同时使用 touchstart 和 touchmove,否则您仍然可以滚动。
  • @jirapong 你介意添加更多代码,这样我就可以看到里面发生了什么......我对此很陌生 - 这就是我所拥有的不起作用:&lt;script language="javascript"&gt; document.body.addEventListener('touchmove', function(e){ e.preventDefault(); }); document.body.addEventListener('touchstart', function(e){ e.preventDefault(); }); &lt;/script&gt;
  • 您是否使用 iPhone/iPad 进行测试?如果是,那么您可以尝试在设置上打开开发人员栏以查看更多详细信息。希望对您有所帮助。
  • @jirapong,谢谢。我用过这个:没关系我用过这个:document.ontouchmove = function(e){ e.preventDefault(); }
  • 这也会杀死所有的点击事件,所以页面上没有任何东西是可点击的。
【解决方案2】:

页面必须从主屏幕启动,元标记才能工作。

【讨论】:

    【解决方案3】:

    这应该可行。顶部或底部不再有灰色区域:)

    <script type="text/javascript">
       function blockMove() {
          event.preventDefault() ;
    }
    </script>
    
    <body ontouchmove="blockMove()">
    

    但这也会禁用任何可滚动区域。如果您想保留可滚动区域并仍然移除顶部和底部的橡皮筋效果,请参见此处:https://github.com/joelambert/ScrollFix

    【讨论】:

    【解决方案4】:

    如果您使用的是 jquery 1.7+,这很好用:

    $("donotscrollme").on("touchmove", false);
    

    【讨论】:

    • 如果你这样做了,有没有办法在“donotscrollme”的子元素上启用滚动?
    • 好问题。你可以试试 $("scrollme").on("touchmove", true); - 不确定这是否可行。
    • @Pirkka Esko - 你可以试试$(elem).removeClass('donotscrollme');
    • @PirkkaEsko 你可以试试 $("parent child").on("touchmove", false);
    【解决方案5】:
    document.ontouchmove = function(e){ 
        e.preventDefault(); 
    }
    

    实际上是我发现的最佳选择,它允许您仍然能够点击输入字段以及使用可拖动的 jQuery UI 拖动内容,但它会阻止页面滚动。

    【讨论】:

      【解决方案6】:

      禁用:

      document.ontouchstart = function(e){ e.preventDefault(); }
      

      启用:

      document.ontouchstart = function(e){ return true; }
      

      【讨论】:

        【解决方案7】:
        document.addEventListener('touchstart', function (e) {
            e.preventDefault();
        });
        

        不要使用ontouchmove 属性来注册事件处理程序,因为您有覆盖现有事件处理程序的风险。请改用addEventListener(请参阅MDN 页面上有关IE 的说明)。

        请注意,阻止 windowdocument 上的 touchstart 事件的默认设置将禁用下降区域的滚动。

        为了防止滚动文档但保持所有其他事件不变,防止touchstart 之后的第一个touchmove 事件默认:

        var firstMove;
        
        window.addEventListener('touchstart', function (e) {
            firstMove = true;
        });
        
        window.addEventListener('touchmove', function (e) {
            if (firstMove) {
                e.preventDefault();
        
                firstMove = false;
            }
        });
        

        这样做的原因是移动版 Safari 使用第一步来确定文档的正文是否正在滚动。我在设计更复杂的解决方案时意识到了这一点。

        如果这将停止工作,更复杂的解决方案是检查 touchTarget 元素及其父元素,并制作可以滚动到的方向图。然后使用第一个touchmove事件来检测滚动方向,看看它是要滚动文档还是目标元素(或目标元素父元素):

        var touchTarget,
            touchScreenX,
            touchScreenY,
            conditionParentUntilTrue,
            disableScroll,
            scrollMap;
        
        conditionParentUntilTrue = function (element, condition) {
            var outcome;
        
            if (element === document.body) {
                return false;
            }
        
            outcome = condition(element);
        
            if (outcome) {
                return true;
            } else {
                return conditionParentUntilTrue(element.parentNode, condition);
            }
        };
        
        window.addEventListener('touchstart', function (e) {
            touchTarget = e.targetTouches[0].target;
            // a boolean map indicating if the element (or either of element parents, excluding the document.body) can be scrolled to the X direction.
            scrollMap = {}
        
            scrollMap.left = conditionParentUntilTrue(touchTarget, function (element) {
                return element.scrollLeft > 0;
            });
        
            scrollMap.top = conditionParentUntilTrue(touchTarget, function (element) {
                return element.scrollTop > 0;
            });
        
            scrollMap.right = conditionParentUntilTrue(touchTarget, function (element) {
                return element.scrollWidth > element.clientWidth &&
                       element.scrollWidth - element.clientWidth > element.scrollLeft;
            });
        
            scrollMap.bottom =conditionParentUntilTrue(touchTarget, function (element) {
                return element.scrollHeight > element.clientHeight &&
                       element.scrollHeight - element.clientHeight > element.scrollTop;
            });
        
            touchScreenX = e.targetTouches[0].screenX;
            touchScreenY = e.targetTouches[0].screenY;
            disableScroll = false;
        });
        
        window.addEventListener('touchmove', function (e) {
            var moveScreenX,
                moveScreenY;
        
            if (disableScroll) {
                e.preventDefault();
        
                return;
            }
        
            moveScreenX = e.targetTouches[0].screenX;
            moveScreenY = e.targetTouches[0].screenY;
        
            if (
                moveScreenX > touchScreenX && scrollMap.left ||
                moveScreenY < touchScreenY && scrollMap.bottom ||
                moveScreenX < touchScreenX && scrollMap.right ||
                moveScreenY > touchScreenY && scrollMap.top
            ) {
                // You are scrolling either the element or its parent.
                // This will not affect document.body scroll.
            } else {
                // This will affect document.body scroll.
        
                e.preventDefault();
        
                disableScroll = true;
            }
        });
        

        这样做的原因是移动版 Safari 使用第一次触摸移动来确定是滚动文档正文还是滚动元素(或目标元素父元素)并坚持这一决定。

        【讨论】:

        • 你先生,值得喝啤酒!
        • 第二个代码 sn-p 非常适合我。谢谢!
        • 如果你能真正把它包装在一个可用的复制和粘贴中,准备使用函数
        • 嗯,它似乎完全阻止了它,这意味着没有任何滚动
        • 似乎firstmove 方法不再适用于iOS 13。现在阻止所有元素滚动。
        【解决方案8】:

        'self.webView.scrollView.bounces = NO;'

        只需在应用程序的 mainViewController.m 文件的“viewDidLoad”中添加这一行。您可以在 Xcode 中打开它并添加它。

        这应该使没有任何橡皮筋反弹的页面仍然可以在应用视图中滚动。

        【讨论】:

        • 已经有一段时间了,但这个答案似乎并不真正适用于这个问题,因为它描述了如何避免在原生 iOS 应用的 scrollView 内滚动。
        【解决方案9】:

        我尝试了上述答案,尤其是 Gajus 的答案,但没有一个有效。最后我找到了下面的答案来解决这个问题,只有主体不滚动,但我的网络应用程序中的其他滚动部分都可以正常工作。 只需为您的身体设置固定位置:

        body {
        
        height: 100%;
        overflow: hidden;
        width: 100%;
        position: fixed;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-02-17
          • 2012-03-29
          • 2013-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多