javascript 防止 iOS WebApp 中的水平滚动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12885625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 17:20:44  来源:igfitidea点击:

Prevent horizontal scroll in iOS WebApp

javascripthtmlioscsshorizontal-scrolling

提问by Staffan Estberg

I've encountered similar problems before and could never really understand the workarounds, and so I ended up relying on plugins like iScroll. This is such simple task that I refuse to include a plugin for it - what I want is to prevent horizontal scroll in iOS. This includes the rubber band effect for any content that might be on the page but that isn't visible.

我以前遇到过类似的问题,永远无法真正理解解决方法,因此我最终依赖于 iScroll 之类的插件。这是一个如此简单的任务,我拒绝为它包含一个插件——我想要的是防止 iOS 中的水平滚动。这包括可能在页面上但不可见的任何内容的橡皮筋效果。

From what I understand I need to disable the rubber band altogether first and then apply the touch scroll to a container element (which I've given the id "touch"). Not sure if this is the right approach?

据我所知,我需要先完全禁用橡皮筋,然后将触摸滚动应用于容器元素(我已将其指定为“触摸”)。不确定这是否是正确的方法?

$(document).bind('touchmove', function(e) {
  if (!e.target == '#touch') {
    e.preventDefault();
  }
});

Style for #touch

#touch的风格

-webkit-overflow-scrolling: touch;
overflow: hidden;
height: 100%;
@media only screen and (max-width: 768px) {
  width: 768px;
}

This doesn't prevent the horizontal width from staying at 728px however, the user is still able to scroll and see the hidden content. Ideas?

这并不能阻止水平宽度保持在 728 像素,但是,用户仍然可以滚动并看到隐藏的内容。想法?

回答by flavian

Well, the above metas are useful as such:

好吧,上面的元数据很有用:

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

They prevent that bug in Safari that happens when the user rotates the screen. However, the most proper way to accomplish the desired functionality is:

它们可以防止 Safari 中用户旋转屏幕时发生的错误。但是,实现所需功能的最正确方法是:

  • Use a parent div with overflow hidden and make sure the height of this div is limited according to the viewport and a child div with overflow:auto or the css 3 overflow-y:scroll. So basically if the size of the content inside the child div exceeds the default size of the child, you can vertically/horizontally scroll through it. Because the parent has overflow:hidden, the content outside of the child will not be displayed, so you get a proper scroll effect. ** Also, if you use overflow: hidden and prevent default for all touchEvents, there will be no scrolling or weird browser behavior**

  • With the help of JavaScript, make sure that every element in the DOM is scaled according to the viewport, so avoid using static sizes for as many elements as possible.

  • Bind the touchStart, touchMove and touchEnd events. Safari doesn't always fire a touchEnd event unless a touchMove event is listened for as well. Even if it's just a placeholder, put it there to avoid the inconsistent behavior in Safari.

  • Horizontal sliding is possible in two ways: load new content in the same div after you detect the slide direction or populate that child div with all the elements and you are good to go and actually shifting the margins/position of the child inside it's parent to 'scroll'. Animation can be used for a slicker interface.

  • Bind your touch event listeners. I don't know what library or event management system you are using, but it doesn't matter. Just call the respective function for the respective task.

  • Get the slide direction(left/right):
  • 使用隐藏溢出的父 div 并确保此 div 的高度根据视口和具有溢出的子 div 限制:自动或 css 3 溢出-y:滚动。所以基本上如果子 div 内的内容大小超过子级的默认大小,您可以垂直/水平滚动它。因为父级有overflow:hidden,子级之外的内容不会显示出来,所以得到了合适的滚动效果。** 此外,如果您使用 overflow: hidden 并阻止所有 touchEvents 的默认设置,则不会出现滚动或奇怪的浏览器行为**

  • 在 JavaScript 的帮助下,确保 DOM 中的每个元素都根据视口进行缩放,因此尽可能避免对尽可能多的元素使用静态大小。

  • 绑定 touchStart、touchMove 和 touchEnd 事件。除非也监听 touchMove 事件,否则 Safari 并不总是触发 touchEnd 事件。即使它只是一个占位符,也要把它放在那里以避免 Safari 中的不一致行为。

  • 水平滑动可以通过两种方式实现:在检测到滑动方向后在同一个 div 中加载新内容,或者使用所有元素填充该子 div 并且你很高兴并且实际上将子元素的边距/位置移动到它的父元素中'滚动'。动画可用于更流畅的界面。

  • 绑定您的触摸事件侦听器。我不知道您使用的是什么库或事件管理系统,但这无关紧要。只需为相应的任务调用相应的函数。

  • 获取滑动方向(左/右):
var slideBeginX; 
function touchStart(event){event.preventDefault();//always prevent default Safari actions
    slideBeginX = event.targetTouches[0].pageX;
};

function touchMove(event) {
event.preventDefault();
// whatever you want to add here
};

function touchEnd(event) {
event.preventDefault();
var slideEndX = event.changedTouches[0].pageX;

// Now add a minimum slide distance so that the links on the page are still clickable
if (Math.abs(slideEndX - slideBeginX) > 200) {
if (slideEndX - slideBeginX > 0) {
// It means the user has scrolled from left to right
} else {
// It means the user has scrolled from right to left.
};
};
};

回答by Anmol Saraf

Following link might be useful to you, here vertical is disabled and horizontal enabled, you just need to tweak the code a little for your purpose.

以下链接可能对您有用,此处禁用垂直并启用水平,您只需要根据自己的目的稍微调整代码即可。

jquery-tools-touch-horizontal-only-disable-vertical-touch

jquery-tools-touch-horizo​​ntal-only-disable-vertical-touch

In case you aren't concerned about vertical sliding, you can try the following code also -

如果你不关心垂直滑动,你也可以试试下面的代码——

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

Hope it helps.

希望能帮助到你。

回答by Daniel De León

This work for me on Android, iPhone and iPad.

这在 Android、iPhone 和 iPad 上对我有用。

<!doctype html>
<html>
    <head>
        <meta content="yes" name="apple-mobile-web-app-capable" />
        <meta content="minimum-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no" name="viewport" />
        <title>Main</title>
    </head>
    <body>
...
    </body>
</html>

回答by lededje

If you dont use the meta you will alwaysget a rubber band effect.

如果您不使用元数据,您将始终获得橡皮筋效果。

<meta name="viewport" content="width=device-width" />

Even if the page fitted exactly the user would still be able to stretch the page wider than it should be able to go, you must use the view port to prevent this, there is no other way...

即使页面完全适合用户仍然能够将页面拉伸得比它应该能够去的更宽,您必须使用视口来防止这种情况发生,没有其他方法......