136

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

我在 ipad 上寻找两件事:如何禁用不需要垂直滚动的页面?以及如何禁用弹性反弹效果?

4

20 回答 20

157

此答案不再适用,除非您正在为非常旧的 iOS 设备进行开发...请参阅其他解决方案


2011 回答:对于在 iOS Safari 中运行的 web/html 应用程序,您需要类似的东西

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

对于 iOS 5,您可能需要考虑以下因素:document.ontouchmove 和 iOS 5 上的滚动

2014 年 9 月更新:可以在这里找到更彻底的方法:https ://github.com/luster-io/prevent-overscroll 。对于这一点以及大量有用的 webapp 建议,请参阅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 指出这一点。

于 2011-10-14T17:17:26.727 回答
123

您还可以将 body/html 的位置更改为固定:

body,
html {
  position: fixed;
}
于 2015-04-14T13:51:31.443 回答
73

为了防止在现代移动浏览器上滚动,您需要添加被动:false。在我找到这个解决方案之前,我一直在努力让它发挥作用。我只在互联网上的另一个地方发现了这一点。

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

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

于 2018-04-16T09:02:43.483 回答
7

您可以使用此 jQuery 代码片段来执行此操作:

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

这将阻止垂直滚动以及页面上发生的任何反弹效果。

于 2013-11-26T12:19:22.757 回答
6
overflow: scroll;
-webkit-overflow-scrolling: touch;

在容器上,您可以在元素内设置反弹效果

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

于 2015-03-20T09:50:28.437 回答
4

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

我遇到的问题是 Swiffy 阶段占据了整个屏幕,因此一旦加载,文档 touchmove 事件就永远不会触发。

如果我尝试将相同的事件添加到 Swiffy 容器,它会在舞台加载后立即被替换。

最后,我通过将 touchmove 事件应用于舞台中的每个 DIV 来解决它(相当混乱)。由于这些 div 也在不断变化,我需要不断检查它们。

这是我的解决方案,似乎效果很好。我希望它对其他试图找到与我相同的解决方案的人有所帮助。

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}
于 2014-03-25T19:25:25.327 回答
4

删除 ipad safari 的代码:禁用滚动和反弹效果

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

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

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
        e.stopPropagation();
    }, { passive: false });
于 2019-04-15T07:28:13.713 回答
3

没有一个解决方案适合我。我就是这样做的。

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }
于 2017-02-05T18:10:45.437 回答
2

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

-webkit-overflow-scrolling: auto

https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling

于 2017-10-13T14:23:37.490 回答
2

试试这个 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 滚动和弹跳手势。

于 2015-09-04T13:24:23.297 回答
1

考虑以下架构:

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

这个 CSS 可以工作:

#root { position: fixed; height: 100%; overflow: auto; }
于 2021-03-02T10:35:01.680 回答
1

对于那些使用 MyScript the Web App 并且正在为身体滚动/拖动(在 iPad 和平板电脑上)而不是实际编写而苦苦挣扎的人:

<body touch-action="none" unresolved>

那为我修好了。

于 2017-06-30T19:24:54.267 回答
1

改进的答案@Ben Bos 并由@Tim 评论

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

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

于 2019-08-14T07:21:42.747 回答
1

试试这个切换webkitOverflowScrolling样式的 JS 解决方案。这里的诀窍是这种风格是关闭的,移动 Safari 进入普通滚动并防止过度反弹 - 唉,它无法取消正在进行的拖动。这个复杂的解决方案还跟踪onscroll顶部的反弹使scrollTop可能被跟踪的负数。此解决方案在 iOS 12.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)
    }
  }
}
于 2019-01-15T17:20:06.540 回答
1

您可以使用 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在您打开/关闭模式时运行/停止功能。

像这样 toggleScroll(true) / toggleScroll(false)

(这仅适用于 iOS,在 Android 上不起作用)

于 2018-02-03T12:33:34.190 回答
0

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

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight
于 2020-06-09T12:34:18.903 回答
0

禁用 safari 反弹滚动效果:

html,
body {
  height: 100%;
  width: 100%;
  overflow: auto;
  position: fixed;
}  
于 2020-07-05T05:51:22.553 回答
0

当带有滚动的菜单打开并且在滚动高度的顶部或底部时,我在后台抓取 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 元素中的任何类型的滚动、触摸或抓取,并且滚动仍在菜单或其他指定的位置工作。干杯。

于 2021-10-07T10:38:31.690 回答
-1

解决方案经过测试,适用于 iOS 12.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;}

希望这会有所帮助~

于 2019-04-15T02:45:04.470 回答
-1

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

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

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}
于 2017-06-12T13:02:07.987 回答