iOS5 -webkit-overflow-scrolling 导致触摸事件停止工作

Posted

技术标签:

【中文标题】iOS5 -webkit-overflow-scrolling 导致触摸事件停止工作【英文标题】:iOS5 -webkit-overflow-scrolling causes touch events to stop working 【发布时间】:2011-12-07 11:40:44 【问题描述】:

当使用[-webkit-overflow-scrolling: touch;]时,滚动区域确实很好用, 但它会导致触摸事件停止滚动区域之外的工作。 有没有人有同样的问题?谁能给我一些关于这个新滚动功能的官方链接?

        <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>ios5 scroll</title>
    <style type="text/css">
    header 
        background: red;
        width: 300px;
        height:44px;
    
    .scroll 
        width: 300px;
        height:300px;
        background: yellow;
        overflow: scroll;
        -webkit-overflow-scrolling: touch;
    
    </style>
    </head>
    <body>
    <div id="container">
        <header>
            <button onclick="alert('header');">won't work?</button>
        </header>
        <div class="scroll">
            <button onclick="alert('scroll');">It works</button>
            <div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div>
            <div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div>
            <div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div><div>text</div>
        </div>
    </div> 
    </body>
    </html>

2011-12-27:我已经解决了这个问题,但我仍然不知道真正的原因。 就我而言,我在一个网页中有几个部分,每个部分都有一个滚动区域和一个标题,每次只显示一个部分,并使用 css3 动画结合变换来切换部分。当在所有部分的滚动区域添加[-webkit-overflow-scrolling]时,触摸事件随机停止工作,所以我只需在当前显示的部分添加[-webkit-overflow-scrolling]并在该部分时将其删除隐。效果很好,但我仍然不知道是什么导致了这个问题。

【问题讨论】:

嗨,你不能做什么?我在 iOS 5 模拟器上运行代码,一切似乎都是可点击和可滚动的。 很抱歉代码运行良好。但是,在一些复杂的情况下,例如如果使用了更多的 css 规则,它确实会导致触摸事件出现问题。顺便问一下,css :active 效果在 ios5 中不起作用吗? 你修好了吗?我也有同样的问题 我在 iOS 5 中遇到了同样的问题。我的标题 div(在滚动元素之前打开/关闭很久)有 4 个链接。当这个类被添加到页面下方的 div 中时,最左边的三个变得不可点击。另一个链接很奇怪。将设备更新到 iOS 6 解决了这个问题。我将通过在需要时仅将类动态添加到可见元素来尝试对 iOS 5 进行相同的修复。 【参考方案1】:

我有同样的问题,我也可以每次都复制它。当 iPad 的方向发生变化时,我有一个页面可以调整元素的大小以适应屏幕。如果在任何时候元素不再需要滚动,即使元素的大小被调整回它需要滚动的位置(例如,为我翻转回横向),它也会停止滚动。所以这绝对是一个错误,但我确实有一个解决方法:

调整元素大小时,我将-webkit-overflow-scrolling 重置为auto,然后将其设置回touch。但是,您必须在两者之间引入延迟(50ms 工作正常,没有尝试更低)。所以我所做的是为元素添加了一个“可滚动”的属性,并使用了下面的代码(使用 jQuery):

$("[scrollable]").css("-webkit-overflow-scrolling", "auto");
window.setTimeout(function ()  $("[scrollable]").css("-webkit-overflow-scrolling", "touch") , 100);

希望这会有所帮助!

【讨论】:

如果可行的话,这听起来很棒!只是为了验证一下,您的页面上有一个&lt;iframe&gt;(任何地方),这样做可以解决滚动问题吗? 这可行,但会导致内容闪烁。有什么建议可以解决这个问题?【参考方案2】:

这是由页面上的&lt;iframe&gt; 引起的。许多脚本创建&lt;iframes&gt; 来完成它们的工作,包括社交跟踪按钮(Facebook、Twitter、G+)、分析跟踪(Google 等)和 PhoneGap 等库。

&lt;iframe&gt; 的显示方式无关紧要。 display: none; visibility: hidden; width: 0; height: 0 没有修复它。如果页面上有&lt;iframe&gt;,它就会发生,有时是间歇性的,有时是总是发生的。

到目前为止,我发现的唯一解决方案(事实证明,在生产应用程序中不太可行)是删除页面上的所有 &lt;iframes&gt;,仅在需要时创建它们(例如,当我需要调用 PhoneGap API),然后在完成后将其删除。

【讨论】:

ThinkingStiff 恰到好处。我们为此苦苦挣扎了好几天,发现删除了用于与 IOS 通信的 iframe,而不是让它闲逛,立即将其清除。这个问题很难重现,因为它会来来去去并影响屏幕的各个部分。 这绝对是一个真正的错误,并为我们移除了 iframe 固定滚动。我们正在使用 iframe 进行 javascript 到 iOS 的通信。我们的解决方法是在创建 iframe 20 毫秒后删除它,并使用 setTimeout 设置 src 属性。如果我们立即将其删除,那么 iOS 将不会收到该消息。我实际上认为超时可能小于 20 毫秒。我尝试了 0 毫秒,它也有效。 当您在急需的 iframe 中遇到问题时,这是非常有问题的。【参考方案3】:

我确认我在使用大量触摸事件和列表滚动的网络应用程序上看到了同样的问题。 在 iOS5 之前,我使用的是 iScroll,一切正常; 在 iOS5 中,我使用 -webkit-overflow-scrolling:touch 滚动列表以获得更快的滚动。

结果是我遇到了随机发生的触摸事件,不再在应用程序的各个部分工作。这些问题通常发生在我滚动列表之后。它会随机影响滚动区域之外的元素,通常是页脚菜单。

在“冻结触摸”状态下重新加载应用程序不会解冻它:要解冻它,我必须关闭 safari 选项卡,打开一个新选项卡并重新加载,直到我在使用应用程序时再次遇到问题。

该问题出现在 iPad2、iPhone 4、iPhone 3GS 以及 iOS 5.0 上

最后,我关闭了溢出触摸滚动并回到了 iScroll,一切都和 iOS4 一样好。

【讨论】:

【参考方案4】:

-webkit-overflow-scrolling + CSS3 动画 + Phonegap API 调用 = 触摸停止响应。

在我调用 Phonegap API 之前,我的 phonegap 应用程序将正常工作,此时触摸将主要停止响应当前视图中附加了事件的第一个元素。我的应用程序的视图是 body > div.current,其余 div 不显示。

我每次都可以复制。

这显然是iOS5的一个bug。

【讨论】:

【参考方案5】:

这里是一些已经列出的答案的变体。

我的具体问题是,当-webkit-overflow-scrolling: touch 应用于元素时,重新定向导致滚动完全停止工作。

示例:横向更短,需要滚动条。肖像足够高,不需要滚动条。重新定位到景观;滚动条存在但不起作用。

监听orientationchange事件

做一些事情来触发滚动元素的布局变化

确保更改足够显着,以至于渲染引擎不会对其进行优化。例如,隐藏然后立即显示似乎没有任何作用。任何使用setTimeout() 的东西似乎都可以工作(也许是不同的执行上下文,我不知道)。

淡入淡出有效,或者隐藏然后稍作延迟显示有效(尽管它会闪烁)。 @Sari 更改滚动属性的解决方案有效,不会导致任何可见的重绘。

$(window).on("orientationchange", function () 
    // use any valid jQuery selector
    var elements = $("[data-touchfix=true]");
    elements.css("-webkit-overflow-scrolling", "auto");
    window.setTimeout(function ()  
            elements.css("-webkit-overflow-scrolling", "touch"); 
        , 100);
);

请注意,除了确保它不会在 Chrome 或 IE 7/8/9 中导致脚本错误之外,我还没有在我的 iPad 3 之外测试过此修复程序。

【讨论】:

我刚刚在 webkit 移动 iOS 5.1.1 上尝试过,但它不起作用。即使将 CSS 属性设置为 autotouchmove 事件仍然不会触发 我没有设计或测试这个来查看触摸事件是否触发。我的问题是触摸滚动条在特定情况下停止响应。如果您可以创建一个小样本来说明您正在尝试完成的内容和无效的内容,那么您绝对应该提出一个新问题。人们(包括我)在-webkit-overflow-scrolling 上遇到了很多麻烦【参考方案6】:

如果这有任何用处...结合 PhoneGap 我使用 Zepto 将 ajax 加载的可滚动内容附加到 dom 中。然后我在它上面应用了一个css转换。页面上没有 iFrame。

我遇到了与此处提到的相同的问题,滚动将停止工作。当我将生成的代码复制到一个单独的文件中并在 iOS 模拟器上尝试时 - 一切都按预期工作。

我最终通过查询父容器的高度来让它工作 - 就在 css 转换之前。通过添加var whatever = $('#container').height(); 滚动工作。

【讨论】:

【参考方案7】:

为了提高一点 ThinkingStiff 的优秀答案,你可以避免眨眼 - 如果溢出:隐藏设置 - 如果只是删除属性而不是“自动”值:

$('.scroll').css('overflow':'hidden','-webkit-overflow-scrolling':'');
window.setTimeout(function ()  $('.scroll').css('overflow':'auto','-webkit-overflow-scrolling':'touch'),50);

【讨论】:

以上是关于iOS5 -webkit-overflow-scrolling 导致触摸事件停止工作的主要内容,如果未能解决你的问题,请参考以下文章

ios5:停止视图被卸载/停止 viewDidUnload 被调用

iOS5 中的图像移动和缩放问题

iOS5 应用未在通知中心列出

iOS5 区域监控准确率

当我们在 ios5.1、ios6 等其他操作系统版本中拥有应用程序时,如何在 ios5 模拟器中启动应用程序?

iOS5 核心数据获取冻结应用