ipad safari:禁用滚动和弹跳效果?

时间:2011-10-14 13:23:04

标签: ipad scroll mobile-safari bounce

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

我正在寻找ipad上的两件事:如何禁用不需要它的页面的垂直滚动? &安培;如何禁用弹性反弹效果?

19 个答案:

答案 0 :(得分:154)

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


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

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

对于iOS 5,您可能需要考虑以下因素:document.ontouchmove and scrolling on 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指出这一点。

答案 1 :(得分:94)

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

body,
html {
  position: fixed;
}

答案 2 :(得分:31)

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

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

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

答案 3 :(得分:7)

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

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

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

答案 4 :(得分: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();
    }
);}

答案 5 :(得分:4)

overflow: scroll;
-webkit-overflow-scrolling: touch;

在容器上,您可以在元素

中设置反弹效果

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

答案 6 :(得分:2)

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

-webkit-overflow-scrolling: auto

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

答案 7 :(得分:2)

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

此css将有助于防止css重新渲染时滚动和性能问题,因为位置已更改/没有宽度和高度的情况下几乎没有滞后现象

<div id="app">
  <v-app>
    <v-content>
      <v-container style="margin-top:40px">

        <v-toolbar flat dark color="primary">
            <v-app-bar-nav-icon></v-app-bar-nav-icon>
            <v-toolbar-title>Title</v-toolbar-title>
            <v-text-field hide-details solo single-line class="ml-5" light></v-text-field>

            <v-spacer></v-spacer>

            <v-divider inset
                       vertical
            ></v-divider>

            <v-btn text class="text-none">
                Action Menu
            </v-btn>

        </v-toolbar>
      </v-container>
    </v-content>
  </v-app>
</div>

答案 8 :(得分:2)

这些解决方案都不适合我。我就是这样做的。

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

答案 9 :(得分:2)

Try this JS sollutuion

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滚动和跳出手势。

答案 10 :(得分:1)

对于那些使用MyScript Web应用程序的人来说,正在努力使用身体滚动/拖动(在iPad和平板电脑上)而不是实际写作:

<body touch-action="none" unresolved>

为我修好了。

答案 11 :(得分: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);
  }
}

而不是在opnen / close模式时运行/停止toggleScroll func。

喜欢这个toggleScroll(true) / toggleScroll(false)

(这仅适用于iOS,在Android上无法正常工作)

答案 12 :(得分:1)

尝试使用此JS解决方案来切换webkitOverflowScrolling样式。这里的技巧是关闭这种样式,移动Safari可以进行普通滚动并防止过度弹跳-a,它无法取消正在进行的拖动。这种复杂的解决方案还跟踪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)
    }
  }
}

答案 13 :(得分:0)

已通过解决方案测试,可在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;}

希望这会有所帮助〜

答案 14 :(得分:0)

要删除ipad Safari的代码:禁用滚动并反弹效果

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

如果文档中有 canvas 标签,有时它将影响Canvas中对象的可用性(例如:对象的移动);因此,请添加以下代码对其进行修复。

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

答案 15 :(得分:0)

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

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

答案 16 :(得分:0)

考虑以下架构:

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

这个 css 会起作用:

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

答案 17 :(得分:-1)

与愤怒的奇异鸟类似,我使用身高而不是位置来工作:

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

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

答案 18 :(得分:-1)

禁用野生动物园跳动滚动效果:

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