Ipad Safari: 禁用滚动和弹跳效果?

我正在开发一个基于浏览器的应用程序,目前我正在为 iPad safari 浏览器开发和设计样式。

我在 ipad 上寻找两样东西: 如何禁用不需要的页面的垂直滚动?(如何禁用弹性反弹效果?)?

239969 次浏览

这个答案不再适用,除非你正在开发一个非常老的 iOS 设备... 请看其他解决方案


2011年的答案: 对于一个运行在 iOS Safari 中的 web/html 应用程序,你需要一些类似的东西

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

对于 iOS5,你可能需要考虑以下因素: 在 iOS5上进行文档移动和滚动

2014年9月更新: 在这里可以找到一种更彻底的方法: https://github.com/luster-io/prevent-overscroll。关于这一点和大量有用的网络应用建议,请参阅 http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

2016年3月更新: 最后一个链接不再活动-请参阅 https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist.html获取存档版本。谢谢@falsarella 指出这一点。

您可以使用这个 jQuery 代码片段来完成以下工作:

$(document).bind(
'touchmove',
function(e) {
e.preventDefault();
}
);

这将阻止垂直滚动和任何反弹效果发生在您的网页。

我知道这有点离谱,但我一直在使用 Swiffy 将 Flash 转换成一个交互式 HTML5游戏,遇到了同样的滚动问题,但没有找到有效的解决方案。

我遇到的问题是 Swiffy stage 占据了整个屏幕,所以一旦加载完成,文档触摸事件就永远不会被触发。

如果我试图将同样的事件添加到 Swiffy 集装箱中,它会在舞台装载后立即被替换。

最后,我通过将触摸事件应用到阶段中的每个 DIV 来解决这个问题(相当混乱)。由于这些 div 也是不断变化的,我需要不断检查它们。

这就是我的解决方案,看起来效果不错。我希望这对其他想找到和我一样解决方案的人有所帮助。

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
'touchmove',
function(e) {
e.preventDefault();
}
);}
overflow: scroll;
-webkit-overflow-scrolling: touch;

在容器上可以设置元素内部的反弹效果

资料来源: http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/

还可以将 body/html 的位置更改为 fix:

body,
html {
position: fixed;
}

试试这个 JS 解决方案 :

var xStart, yStart = 0;


document.addEventListener('touchstart', function(e) {
xStart = e.touches[0].screenX;
yStart = e.touches[0].screenY;
});


document.addEventListener('touchmove', function(e) {
var xMovement = Math.abs(e.touches[0].screenX - xStart);
var yMovement = Math.abs(e.touches[0].screenY - yStart);
if((yMovement * 3) > xMovement) {
e.preventDefault();
}
});

防止默认的 Safari 滚动和弹出手势而不分离您的触摸事件侦听器。

没有一个解决方案对我有效,我就是这么做的。

  html,body {
position: fixed;
overflow: hidden;
}
.the_element_that_you_want_to_have_scrolling{
-webkit-overflow-scrolling: touch;
}

类似于愤怒的猕猴桃,我使用身高而不是位置来工作:

html,body {
height: 100%;
overflow: hidden;
}


.the_element_that_you_want_to_have_scrolling{
-webkit-overflow-scrolling: touch;
}

对于那些使用 MyScript 这个网络应用程序的人来说,他们在 iPad 和平板电脑上使用滚动/拖动身体来代替实际写作:

<body touch-action="none" unresolved>

这就解决了我的问题。

在 iphone 上测试。只要在目标元素容器上使用这个 css,它就会改变滚动行为,当手指离开屏幕时,滚动行为就会停止。

-webkit-overflow-scrolling: auto

Https://developer.mozilla.org/en-us/docs/web/css/-webkit-overflow-scrolling

你可以使用 js 来防止滚动:

let body = document.body;


let hideScroll = function(e) {
e.preventDefault();
};


function toggleScroll (bool) {


if (bool === true) {
body.addEventListener("touchmove", hideScroll);
} else {
body.removeEventListener("touchmove", hideScroll);
}
}

而不仅仅是运行/停止 toggleScroll函数时,您的 opnen/关闭模式。

就像这个 toggleScroll(true) / toggleScroll(false)

(这只适用于 iOS 系统,安卓系统无法运行)

为了防止在现代移动浏览器上滚动,您需要添加被动: false。在找到解决办法之前,我一直费尽心思想让这个方法奏效。我只在互联网上的另一个地方发现过这个。

function preventDefault(e){
e.preventDefault();
}


function disableScroll(){
document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
document.body.removeEventListener('touchmove', preventDefault);
}

尝试这个切换 webkitOverflowScrolling样式的 JS 解决方案。这里的诀窍是,这种风格是关闭的,移动 Safari 去普通滚动,并防止过度反弹ーー唉,它不能取消正在进行的拖动。这种复杂的解决方案也跟踪 onscroll作为反弹超过顶部使 scrollTop负,可能被跟踪。这个解决方案在 iOS12.1.1上进行了测试,并且有一个缺点: 当加速滚动时仍然会发生单次反弹,因为重置样式可能不会立即取消。

function preventScrollVerticalBounceEffect(container) {
setTouchScroll(true) //!: enable before the first scroll attempt


container.addEventListener("touchstart", onTouchStart)
container.addEventListener("touchmove", onTouch, { passive: false })
container.addEventListener("touchend", onTouchEnd)
container.addEventListener("scroll", onScroll)


function isTouchScroll() {
return !!container.style.webkitOverflowScrolling
}


let prevScrollTop = 0, prevTouchY, opid = 0


function setTouchScroll(on) {
container.style.webkitOverflowScrolling = on ? "touch" : null


//Hint: auto-enabling after a small pause makes the start
// smoothly accelerated as required. After the pause the
// scroll position is settled, and there is no delta to
// make over-bounce by dragging the finger. But still,
// accelerated content makes short single over-bounce
// as acceleration may not be off instantly.


const xopid = ++opid
!on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)


if(!on && container.scrollTop < 16)
container.scrollTop = 0
prevScrollTop = container.scrollTop
}


function isBounceOverTop() {
const dY = container.scrollTop - prevScrollTop
return dY < 0 && container.scrollTop < 16
}


function isBounceOverBottom(touchY) {
const dY = touchY - prevTouchY


//Hint: trying to bounce over the bottom, the finger moves
// up the screen, thus Y becomes smaller. We prevent this.


return dY < 0 && container.scrollHeight - 16 <=
container.scrollTop + container.offsetHeight
}


function onTouchStart(e) {
prevTouchY = e.touches[0].pageY
}


function onTouch(e) {
const touchY = e.touches[0].pageY


if(isBounceOverBottom(touchY)) {
if(isTouchScroll())
setTouchScroll(false)
e.preventDefault()
}


prevTouchY = touchY
}


function onTouchEnd() {
prevTouchY = undefined
}


function onScroll() {
if(isTouchScroll() && isBounceOverTop()) {
setTouchScroll(false)
}
}
}

解决方案经过测试,可以在 iOS12.x 上运行

这就是我遇到的问题:

<body> <!-- the whole body can be scroll vertically -->
<article>


<my_gallery> <!-- some picture gallery, can be scroll horizontally -->
</my_gallery>


</article>
</body>

当我滚动我的画廊,身体总是滚动本身(人类滑动不是真正的水平) ,这使我的画廊无用。

我的画廊开始滚动时,我是这么做的

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

当我的画廊结束它的滚动..。

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

希望这对你有帮助

移除 ipad Safari 的代码: 禁用滚动和弹出效果

   document.addEventListener("touchmove", function (e) {
e.preventDefault();
}, { passive: false });

如果文档中有 帆布标签,有时会影响画布中对象的可用性(例如: 对象的移动) ; 所以添加下面的代码来修复它。

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
e.stopPropagation();
}, { passive: false });

改进的回答: “ Ben Bos”,评论: “ Tim”

这个 css 将有助于防止滚动和性能问题的 css 重新渲染,因为位置变化/没有宽度和高度的小滞后

html,
body {
position: fixed;
width: 100%;
height: 100%
}


对于那些不想消除跳动但只想知道跳动何时停止(例如开始计算屏幕距离)的人来说,可以执行以下操作(容器是溢出的容器元素) :

    const isBouncing = this.container.scrollTop < 0 ||
this.container.scrollTop + this.container.offsetHeight >
this.container.scrollHeight

禁用 Safari 弹跳滚动效果:

html,
body {
height: 100%;
width: 100%;
overflow: auto;
position: fixed;
}

考虑以下架构:

<body> <div id="root"></div> </body>

这个 css 将工作:

#root { position: fixed; height: 100%; overflow: auto; }

当一个带有滚动的菜单打开时,在滚动高度的顶部或底部,我在抓取背景中的 html 元素时遇到了一个问题。我试过很多方法。将 html 位置设置为 fixed是我最接近锁定屏幕的方法,但是在 PWA 中,它导致底部出现一个白色区域,我无法修复。 最后,我找到了一个对我有效的解决办法:

html {
width: 100%;
height: 100%;
overflow: hidden;
}


body {
margin: 0;
height: calc(100vh - 1px)
overflow: hidden;
background-color: 'Whatever color you need to hide the 1px at the bottom'
}

因为这似乎只是 iOS 上的一个问题,所以我把目标对准了从 iPhone X 到12 Pro Max 的设备:

body {
margin: 0;
overflow: hidden;
background-color: '#TIP: You can use the color picker from the inspector';


@media only screen and (min-width: 375px) and (max-height: 926px) and (-webkit-device-pixel-ratio: 3) {
height: calc(100vh - 1px);
}
}

这是防止任何类型的滚动,触摸或抓取在 html 或体元素,滚动仍然在菜单中工作或在其他指定的地方。干杯。

body {
touch-action:none;
}

使用 JQuery

// Disable
$("body").css({ "touch-action": "none" })


// Enable
$("body").css({ "touch-action": "auto" })