-webkit-overflow-scrolling: touch;在苹果iOS8中出现问题

57

我正在开发一个 web 应用程序,在多个地方使用 -webkit-overflow-scrolling:touch 属性,以使溢出的 div 具有惯性滚动效果。

自 iOS8 更新以来,-webkit-overflow-scrolling: touch 进行滚动时会停止工作,目前我唯一解决这个问题的方法是删除 -webkit-overflow-scrolling: touch 属性,这会导致标准的粘滞滚动。请帮忙!

以下是一个在 iOS5、6 和 7 中正常工作的标准类的示例:

.dashboardScroll {
    height: 100%;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch; /*MAKES OVERFLOWN OBJECTS HAVE INERTIA SCROLLING*/
    -webkit-transform: translateZ(0px); /*HELPS THE ABOVE WORK IN IOS5*/
} 

有人成功防止iPad进行粘性滚动而不是滚动所需的div吗? - tomazahlin
惯性滚动在 iPhone 6 上的 iOS 8.1 模拟器中,在 此 JSBin 中正常工作。 - Alexander O'Mara
http://patrickmuff.ch/blog/2014/10/01/how-we-fixed-the-webkit-overflow-scrolling-touch-bug-on-ios/ - Frane Poljak
这可能会有帮助:https://dev59.com/318d5IYBdhLWcg3wgya4#26743685 - Alex
嗨,Alex,我已经实现了类似的东西,但还是谢谢你的建议。我希望真正的解决方案现在已经浮出水面了,但看起来可能性不大。 - Jamie Beech
显示剩余13条评论
11个回答

29

我曾经遇到一个类似的问题,是一个相当复杂的嵌套可滚动的 div,在 iOS 5、6 和 7 上可以正常滚动,但在 iOS 8.1 中出现了间歇性的无法滚动。

我找到的解决方法是删除所有欺骗浏览器使用 GPU 的 CSS:

-webkit-transform: translateZ(0px);
-webkit-transform: translate3d(0,0,0);
-webkit-perspective: 1000;

通过这样做,'-webkit-overflow-scrolling: touch;' 仍然可以包含并像正常一样工作。

这意味着我放弃了早期iOS版本中上述技巧提高滚动性能的(对我来说,存疑)收益,但在惯性滚动和性能之间选择时,惯性滚动被认为更重要(我们不再支持iOS 5)。

我目前还不能确定为什么会出现这种冲突;可能是这些功能的实现有问题,但我怀疑CSS中存在一些更深层次的原因。我正在尝试创建一个简化的HTML/CSS/JS配置文件来演示它,但也许需要大量的动态数据和繁重的标记结构才能发生这种情况。

补充:但是,我必须向我们的客户指出,即使使用此修复程序,用户开始尝试在不可滚动的元素上滚动时,她在停止后必须等待一秒钟才能滚动可滚动的元素。这是本机行为。


我的临时解决方案是将所有这些都移除,但现在我只能使用标准的粘性滚动。暂时可以用,但它确实破坏了应用程序的用户体验,所以我不能说这是解决方案,而更像是一个临时措施。 - Jamie Beech
@Jamie 在删除其他CSS后,我能够使用-webkit-overflow-scrolling: touch;。这对你不起作用吗?由于我是通过试错法得出这个结果的,所以我不确定还有什么其他建议。当然,这是从iOS 7到iOS 8的行为变化,所以谁知道...也许它会在补丁中修复。 - Louis Féat
嘿,非常抱歉回复晚了。不,这个解决方案对我没有用。在花费了相当多的时间寻找解决方案后,我有点放弃了。 - Jamie Beech
1
嘿,我也遇到了同样的问题,这个解决方案无法修复,我正在使用iOS11。 - madhuiOS

9

我曾经遇到这个问题并找到了解决方案。解决方案是将您的内容放入两个容器中,例如:(.dashboardScroll > .dashboardScroll-inner),并通过此css3属性使内部容器“.dashboardScroll-inner”的高度比父级“.dashboardScroll”多1个像素。

.dashboardScroll-inner { height: calc(100% + 1px);}

请查看以下内容:

http://patrickmuff.ch/blog/2014/10/01/how-we-fixed-the-webkit-overflow-scrolling-touch-bug-on-ios/

如果无法添加其他容器,请使用此方法:

.dashboardScroll:after { height: calc(100% + 1px);}

1
没错,这个对我有用。LESS:.content-scrollable { .position(absolute, 0, 0, 0, 0); background: @color-empty; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; } .content-scrollable-inner { height: calc(100% + 1px); }HTML:
<动态生成的内容的其余部分>
- Kapil Pendse

6
我在Cordova web应用程序中遇到了同样的问题。对我来说,问题在于我有一个父级 <div>被动画化并具有属性animation-fill-mode: forwards;。删除此属性解决了问题,并修复了破损的overflow-scrolling。

1
防止触摸事件从周围元素冒泡到DOM是另一个潜在的解决方案。您可能会注意到,在周围DIV元素接收触摸或拖动事件时,滚动会停止。我们在一个需要平稳滚动的菜单中遇到了这个问题,关闭这些事件可以帮助停止可滚动元素的“黏滞”。
$html.bind('touchmove', scrollLock );

var scrollLock = function(e) {
        if( $body.hasClass('menu-open') ){
                e.stopPropagation();
                e.preventDefault();
        }
};

$html.unbind('touchmove', scrollLock );

1

我无法通过以前的答案解决问题,所以几个小时后我尝试了iScroll库。我知道为了只为iOS添加滚动而包含一个额外的库(相当大)并不是很好,但这对我有效。只需按照自述文档操作,使用lite版本即可。

缺点:

  • 在Android上滚动现在看起来像垃圾,不再是本地的了。
  • 不再能够通过滚动刷新页面
  • 您需要为Android应用另一个修复程序:点击无效

我不确定是否会使用它,但如果您需要,请尝试一下。


1

我尝试了这里的所有解决方案,但都没有成功。我通过在可滚动的div和父容器上都加上属性-webkit-overflow-scrolling:touch;来让它工作。

div.container {
    -webkit-overflow-scrolling: touch;
}

div.container > div.scrollable {
    -webkit-overflow-scrolling: touch;
    overflow-y: auto;
}

0

我也遇到了一些麻烦,只是情形稍有不同。

我的div具有惯性且没有任何问题。

我有一个简单的JSFiddle可以供您查看。

https://jsfiddle.net/SergioM/57f2da87/17/

.scrollable {
    width:100%;
    height:200px;
    -webkit-overflow-scrolling:touch;
    overflow:scroll;
}

希望能有所帮助。


如果还没有帮助,请尝试创建一个fiddle来重现您的问题,我会帮您解决。 - SergioM

0
我的问题是 body 具有来自 body-scroll-lock.jsposition:fixed。移除它后一切都正常工作了。

0

我使用了Mohammed Suleiman答案中的最后一种方法(.dashboardScroll:after { height: calc(100% + 1px);}),但结果是我的内容下面有一个100% + 1px的空白区域。我通过在500毫秒后将高度改回1像素来解决这个问题。虽然不太美观,但它能正常工作。

这是一个React.js应用程序,所以我的代码如下:

componentDidUpdate() {
    if (window.navigator.standalone && /* test for iOS */) {
        var self = this;
        setTimeout(function(){
            self.refs.style.innerHTML = "#content::after { height: 1px}";
        }, 500);
    }
}

并渲染:

render() {
    var style = '';
    if (window.navigator.standalone && /* test for iOS */) {
        style = "#content::after { height: calc(100% + 1px)}";
    }
    return (<div>
                <style type="text/css" ref="style">
                    {style}
                </style>
                <div id="content"></div>
            </div>);
}

0

我在使用Angular Bootstrap模态框时遇到了这个问题。我通过创建自己的样式表并在媒体查询中删除固定宽度和边距来解决了它。

原文:

  .modal-dialog {
    position: relative;
    width: auto;
    margin: 10px;
  }

@media (min-width: 768px) {
  .modal-dialog {
      width: 600px;
      margin: 30px auto;
  }
    .modal-content {
        -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    }
    .modal-sm {
        width: 300px;
    }
}
@media (min-width: 992px) {
    .modal-lg {
        width: 900px;
    }
}

变更:

.modal-dialog {
    margin: 0px;
    margin-top: 30px;
    margin-left: 5%;
    margin-right: 5%;
}

@media (min-width: 768px) {
    .modal-dialog {
        width: auto;
        margin-left: 10%;
        margin-right: 10%;
    }
    .modal-content {
       -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
       box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    }
}

@media (min-width: 992px) {
    .modal-dialog {
        width: auto;
        margin-left: 15%;
        margin-right: 15%;
    }  
}

...那恢复了惯性滚动吗? - canon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接