`-webkit-overflow-scrolling: touch` 在 iOS7 中因最初的屏幕外元素而损坏

Posted

技术标签:

【中文标题】`-webkit-overflow-scrolling: touch` 在 iOS7 中因最初的屏幕外元素而损坏【英文标题】:`-webkit-overflow-scrolling: touch` broken for initially offscreen elements in iOS7 【发布时间】:2013-09-15 04:32:03 【问题描述】:

GM种子已经放出来了,我们可以聊聊啦!

看起来在 ios7 中“-webkit-overflow-scrolling: touch”坏了。最初不在屏幕上的元素的触摸事件不会触发(或者在某些情况下只是不可靠的)。

这是一个例子:

<!DOCTYPE html><html>
    <head><title>TEST</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="apple-mobile-web-app-capable" content="yes" />
    <style>

        #scrollbox 
                position: fixed;
                top: 0px;
                width: 100%;
                height: 100%;
                overflow: scroll;
                -webkit-overflow-scrolling: touch;
        

        .touchDiv 
            position: relative;
            width:100%;
            height:80px;
            background-color: #FFBBBB;
        

        ul, li 
            text-indent: 0px;
            list-style: none;
            padding: 0px;
            margin: 0px;
        

        li 
            padding-top: 10px;
            padding-bottom: 10px;
            border-bottom: 1px solid #333;
        

    </style>
    <script type="text/javascript">

        function onBodyLoad() 
            var touchDiv = document.getElementById("bottomDiv");
            touchDiv.ontouchstart = function(e) 
                alert("touched");
            ;

            touchDiv = document.getElementById("topDiv");
            touchDiv.ontouchstart = function(e) 
                alert("touched");
            ;
        
    </script>
    </head>


    <body onload="onBodyLoad()">


        <div id='scrollbox'>
                <div id="topDiv" class="touchDiv">Fires an event when touched</div>
                <ul>
                    <li><a href='#' onclick="alert('1')">Link 1</a></li>
                    <li><a href='#' onclick="alert('3')">Link 3</a></li>
                    <li><a href='#' onclick="alert('4')">Link 4</a></li>
                    <li><a href='#' onclick="alert('5')">Link 5</a></li>
                    <li><a href='#' onclick="alert('6')">Link 6</a></li>
                    <li><a href='#' onclick="alert('7')">Link 7</a></li>
                    <li><a href='#' onclick="alert('8')">Link 8</a></li>
                    <li><a href='#' onclick="alert('9')">Link 9</a></li>
                    <li><a href='#' onclick="alert('10')">Link 10</a></li>
                    <li><a href='#' onclick="alert('11')">Link 11</a></li>
                    <li><a href='#' onclick="alert('12')">Link 12</a></li>
                    <li><a href='#' onclick="alert('13')">Link 13</a></li>
                    <li><a href='#' onclick="alert('14')">Link 14</a></li>
                    <li><a href='#' onclick="alert('15')">Link 15</a></li>
                    <li><a href='#' onclick="alert('16')">Link 16</a></li>
                    <li><a href='#' onclick="alert('17')">Link 17</a></li>
                    <li><a href='#' onclick="alert('18')">Link 18</a></li>
                    <li><a href='#' onclick="alert('19')">Link 19</a></li>
                    <li><a href='#' onclick="alert('20')">Link 20</a></li>
                    <li><a href='#' onclick="alert('21')">Link 21</a></li>
                    <li><a href='#' ontouchstart="alert('22')">Link 22</a></li>
                </ul>
                <div id="bottomDiv" class="touchDiv">Fires an event when touched 2</div>

        </div>

</body>

我想这会破坏大多数移动优化的网络应用程序。

上面的代码有什么问题吗?和/或是否有任何解决方法?

(我已经向苹果提出了一个错误 - 前段时间,没有回应)

【问题讨论】:

这个***.com/questions/7763458/… 似乎有问题的历史 - 尽管问题略有不同。 【参考方案1】:

apple dev forums 上似乎有解决此问题的方法

非常感谢 Baicoianu 先生。

基本上你需要监听父滚动 div 上的触摸事件。所以在我的情况下添加:

document.getElementById("scrollbox").addEventListener('touchstart', function(event));

到 onBodyLoad 函数。

我猜这是一些事件传播问题,通过更高级别的监听解决。

【讨论】:

这在应用时会在我的网站上引起一些有趣的行为。某些图像无法加载(仅在 iOS 设备上)。我无法解释它,但我能够隔离这种行为。 很高兴您发现我的回答很有用!不久前我向他们提交了一份 Radar 错误报告——也许如果更多的开发者提交这个错误,它将获得 Apple 更高的优先级。 这个解决方案对我有用。当然,作为目标的元素我 WANT 深深地嵌套在父级中 - 因此事件需要通过多个级别冒泡,直到它到达父级滚动 div。我想知道这种方法的性能影响是什么?你有什么想法吗? 因为这只发生在 touchstart 上,我的印象是效果可以忽略不计,除非你的元素是 1000 深的父元素 - 在这种情况下你可能需要重新设计! 最简单的测试方法是在调试控制台中,至少在 Safari 中针对 IOS 模拟器运行调试器时,我必须用单引号编写它,而不是双引号:document.getElementById('scrollbox').addEventListener('touchstart', function(event)); 但它解决了我的问题:IOS7 中的奇怪行为(空白触摸区),特别是在使用绝对定位的 div 时。【参考方案2】:

以上答案对我来说是一种享受。这是上述修复的 jQuery 版本:

$('#scrollbox').on('touchstart', function(event));

【讨论】:

以上是关于`-webkit-overflow-scrolling: touch` 在 iOS7 中因最初的屏幕外元素而损坏的主要内容,如果未能解决你的问题,请参考以下文章