在 iPhone Web 应用程序中禁用滚动?

Posted

技术标签:

【中文标题】在 iPhone Web 应用程序中禁用滚动?【英文标题】:Disable scrolling in an iPhone web application? 【发布时间】: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(); 【参考方案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。

【讨论】:

该 bit.ly 链接不起作用。你有原始网址吗? 链接是github.com/joelambert/ScrollFix。如果自定义域上的 bit.ly 链接停止工作,只需将域更改为 bit.ly(此链接变为 bit.ly/uaIgUn)【参考方案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;

【讨论】:

以上是关于在 iPhone Web 应用程序中禁用滚动?的主要内容,如果未能解决你的问题,请参考以下文章

Web 应用程序,Android 与 Iphone 滚动

如何在 iPhone 的 html 中禁用水平滚动

防止缓存 iPhone Web 应用程序重新加载(滚动到顶部)

想要专注,但不想滚动 iPhone 网络应用

使用 Titanium 滚动时禁用 TableView 垂直反弹

在 Iphone 上禁用 Progressive Web App 上的后退按钮