【问题标题】:-webkit-overflow-scrolling: touch; breaks in Apple's iOS8-webkit-溢出滚动:触摸;苹果 iOS8 中断
【发布时间】:2014-10-03 09:12:29
【问题描述】:

我正在开发一个网络应用程序,该应用程序在多个地方使用-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*/
} 

【问题讨论】:

  • iOS5 中也存在同样的错误(iPad1 的最终更新)。
  • 此外,我在 Android AOSP 上的触摸滚动中遇到了一些非常奇怪的错误,这些错误通过使用 position:relative; 来修复。和溢出:隐藏;在内容上(或可滚动的 div?!)。错误以 2 倍的手指移动滚动,不滚动,抖动的标题和滚动跟踪器的遮挡。
  • 这绝对和iOS5的bug不一样,因为如果你看我的代码,我已经修复了。我认为这与 iOS8 现在识别滚动事件有关,这对于使用视差的网站来说非常棒,但会破坏溢出滚动。
  • 完全相同的 CSS 对我有用。
  • 这是在 iOS 8 iPad 上吗?

标签: scroll ios8 webkit overflow


【解决方案1】:

我有一个(相当复杂的)嵌套可滚动 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;'仍然可以包含在内并且仍然正常运行。

这确实意味着牺牲(对我来说,可疑的)滚动性能增益,上述 hack 在早期版本的 iOS 中提供,但在选择惯性滚动和惯性滚动时,惯性滚动被认为更重要(我们不这样做) '不再支持 iOS 5)。

现阶段我无法说明为什么会存在这种冲突;可能是这些特性的一个糟糕的实现,但我怀疑在 CSS 中有一些更深层次的东西导致了它。我目前正在尝试创建一个精简的 HTML/CSS/JS 配置来演示它,但可能需要繁重的标记结构和大量的动态数据才能实现。

附录:但是,我确实必须向我们的客户指出,即使使用此修复程序,用户也开始尝试在不可滚动的元素上滚动,她将不得不等待一秒钟后在能够滚动可滚动元素之前停止。这是原生行为。

【讨论】:

  • 我的临时解决方案是删除所有这些,但现在我只剩下标准的粘性滚动了。它现在可以,但它确实破坏了应用程序的用户体验,所以我不会说这是修复,而是更多的临时措施。
  • @Jamie 我可以使用 -webkit-overflow-scrolling: touch;删除其他 CSS 后。这对你不起作用吗?当我通过反复试验得出这个结论时,我不确定还有什么建议。当然,这是从 iOS 7 到 iOS 8 的行为变化,所以谁知道……也许它会在补丁中修复。
  • 嘿,很抱歉回复晚了。不,这个解决方案对我不起作用。在花了很多时间试图找到解决方案后,我有点放弃了。
  • 嘿,即使我也面临同样的问题,这个解决方案无法修复,我正在使用 ios11
【解决方案2】:

我遇到了这个问题并找到了解决方案。解决方案是,您必须将内容放入两个容器中,例如:(.dashboardScroll > .dashboardScroll-inner),并通过这个 css3 让内部容器“.dashboardScroll-inner”比父级“.dashboardScroll”高 1px属性

.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);}

【讨论】:

  • 是的,为我解决了这个问题。 LESS: .content-scrollable { .position(absolute, 0, 0, 0, 0);背景:@color-empty;溢出-x:隐藏;溢出-y:自动; -webkit-溢出滚动:触摸; } .content-scrollable-inner { 高度:计算(100% + 1px); } HTML:
    >
【解决方案3】:

我在 Cordova 网络应用程序中遇到了同样的问题。对我来说,问题是我有一个父 <div> 是动画的并且有属性 animation-fill-mode: forwards;

删除此属性解决了问题并修复了损坏的溢出滚动。

【讨论】:

    【解决方案4】:

    我无法用以前的答案解决问题。所以几个小时后,a 尝试了 iScroll 库,iScroll。我知道包括一个额外的库(并且相当大)来为 iOS 添加滚动并不是很好,但这对我有用。跟着readme就行了,lite版就够了。

    缺点:

    • 现在在 Android 上滚动看起来像垃圾,它不再是原生的了。
    • 无法再通过滚动来刷新页面
    • 您需要为 Android 应用另一个修复程序:Clicks not working

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        防止来自周围元素的触摸事件在 DOM 中冒泡是另一个潜在的解决方案,您可能会注意到当周围的 DIV 元素接收到触摸或拖动事件时滚动停止。我们在需要平滑滚动的菜单中遇到了这个特殊问题。关闭这些事件有助于阻止可滚动元素的“粘连”。

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

        【讨论】:

          【解决方案7】:

          我也遇到了一些麻烦,但情况略有不同。

          我的 div 确实有惯性,没有任何问题。

          我有一个简单的 JSFiddle,你可以看看。

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

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

          希望对你有帮助。

          【讨论】:

          • 如果仍然没有帮助,请尝试创建一个小提琴来重现您的问题,我会看看。
          【解决方案8】:

          我在 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>);
          }
          

          【讨论】:

            【解决方案9】:

            我在使用角度引导模式时遇到了这个问题。我通过创建自己的样式表并删除媒体查询中的固定宽度和边距来修复它。

            原文:

              .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%;
                }  
            }
            

            【讨论】:

            • ...恢复惯性滚动?
            【解决方案10】:

            我通过使用 jquery 将一些内联 css 添加到可滚动 div 来解决我的问题。在加载 dom 后将 css 添加到 div 使滚动工作。

            $('.lightbox__scrollable-content').css('overflow-y', 'scroll');
            

            【讨论】:

              【解决方案11】:

              我的问题是body 有来自body-scroll-lock.jsposition:fixed。删除它,一切正常。

              【讨论】:

                猜你喜欢
                • 2017-04-05
                • 2012-02-23
                • 1970-01-01
                • 1970-01-01
                • 2012-06-05
                • 1970-01-01
                • 2015-03-12
                • 2015-01-17
                • 1970-01-01
                相关资源
                最近更新 更多