使用 -webkit-overflow-scrolling:touch - Safari iOS javascript 事件 (scrollTop / scrollLeft) 时的当前滚动位置

Posted

技术标签:

【中文标题】使用 -webkit-overflow-scrolling:touch - Safari iOS javascript 事件 (scrollTop / scrollLeft) 时的当前滚动位置【英文标题】:Current scroll position when using -webkit-overflow-scrolling:touch - Safari iOS javascript event (scrollTop / scrollLeft) 【发布时间】:2012-01-22 17:30:09 【问题描述】:

我正在使用 -webkit-overflow-scrolling:touch 来制作一个带有溢出的 div:scroll;平滑滚动 ios 触摸事件。

它工作得非常好,只是它在滚动时似乎没有更新 element.scrollTop 或 element.scrollLeft。它只更新 element.scrollTop / 当动量耗尽并停止时触发滚动事件。

有谁知道找出当前滚动位置的方法以及是否有我可以监听的事件?我想知道是否可以通过 CSS3 属性找到它?谢谢

下面的示例显示了两次尝试:

<!DOCTYPE html>
<body>
    <div id="display_a">Scroll is: 0</div>
    <div id="display_b">Scroll is: 0</div>  
    <div id="element" style="width:800px;overflow-x:scroll;-webkit-overflow-scrolling:touch;">
        <div style="font-size:100px;width:1850px;">
            a b c d e f g h i j k l m n o p q r s t u v w x y z
        </div>
    </div>
    <script>
        var e = document.getElementById("element");
        var display_a = document.getElementById("display_a");
        var display_b = document.getElementById("display_b");
        e.addEventListener("scroll",function(event)display_a.innerHTML = "Scroll is: " + event.target.scrollLeft;);
        setInterval(function()display_b.innerHTML = "Scroll is: " +  e.scrollLeft;,100);
    </script>   
</body>
</html>

============ 更新============

iOS 8 已经对这种行为进行了排序。滚动事件现在在滚动时触发。

请注意,您现在必须在反弹滚动期间处理负滚动值。

【问题讨论】:

只想对迄今为止做出贡献的所有人表示非常感谢,我担心我们不会找到完美的解决方案,但下面有一些很好的建议。 iOS >8.x上的3rd-party浏览器问题依然存在 滚动事件不会在主屏幕 webapps 或 UIWebView 中触发 【参考方案1】:

这是我的存储库,我在其中添加了回调 onScrolling(),以便让我知道动量滚动动画何时发生在 animate():https://github.com/simpleshadow/iscroll/blob/master/src/iscroll.js

我在这里使用他的建议制作了一个示例应用程序:http://jsfiddle.net/simpleshadow/wQQEM/22/

Github 上的@robertlawson86 提出了这个建议,以帮助提供关于在动量滚动期间何时抓取位置的想法。查看示例和讨论:https://github.com/cubiq/iscroll/issues/183

【讨论】:

【参考方案2】:

在滚动时获取水平滚动条的位置(通过 css overflow-y:scroll)

$('#myNode').bind('scroll', function(e)
  var myPos = e.target.scrollLeft;
  // do something with myPos but don't naughty
)

【讨论】:

这假定一个 jQuery 依赖项【参考方案3】:

我知道这很奇怪,但你可以通过注册 touchstart 事件来跟踪 scrollLeft/scrollTop:

e.addEventListener("touchstart",function(event));

【讨论】:

感谢大卫,但在您将手指放在触摸屏上之后,这肯定无济于事,它只是保持滚动的动力。还是我错过了什么?【参考方案4】:

在类似的情况下,我正在使用scrollability.js,它在模拟本机滚动行为方面做得非常好。然后我正在监听“scrollability-start”事件并监视滚动元素的顶部/左侧属性。我知道这并不理想,但它是一个不错的选择。

【讨论】:

我不得不说,它在模拟 iOS 样式滚动方面确实做得很好!我一定会适当地看一看某个点。感谢您的建议 也看看iScroll,它做同样的事情,但我发现因为像scrollTo()和scrollToElement()这样的方法更有用。【参考方案5】:

如果有帮助,scrollTop 和 scrollLeft 会在 touchmove 事件处理程序中实时更新:

$(function()

    var $div = $("#scroll")
    var $p   = $("#display");

    var update = function(e)
    
        $p.text( e.type +": "+ $div.scrollLeft() +", "+ $div.scrollTop() );
    

    $div.bind( "touchmove", update )
        .bind( "scroll",    update );
);

【讨论】:

请注意,如果你想让它在屏幕上保持静态元素,iOS 5 引入了 position:fixed CSS。 这假定一个 jQuery 依赖项 JQuery 用于简短的工作演示;没有它,scrollTop、scrollLeft 和 touchmove 是标准的。【参考方案6】:

这可能会有所帮助。这是一个 jQuery 解决方案,我用来在 IOS 左右滑动时强制分页。这与您正在工作的情况不完全相同。我正在使用与“触摸”版本不同的“溢出滚动:自动”。

#yourDiv 
    -webkit-overflow-scrolling: auto;
    overflow:auto;

我使用“overflow-scrolling:auto”,因为它对 touchend 事件的反应更快。不幸的是,“overflow-scrolling:touch”在运行时似乎确实可以抵抗 javascript 和 CSS 动画。但至少你可以在滚动过程中从中得到一些位置信息。

var pageSwiping = false;

$('#yourDiv').on('scroll', function(e) 
    if (pageSwiping !== true  ) 
        pageSwiping = true;
        var offset = $('#'+e.target.id).scrollLeft();
        $('#yourDiv').one( 'touchend',elem:e.target.id,dragStart:offset,divMove);
    ;
);

var divMove = function(e) 
    pageSwiping = false;
    var elem = e.data.elem;
    var dragEnd = $('#'+elem).scrollLeft();
    var dragDelta = (dragEnd - e.data.dragStart)
        // Make page-alignment decisions based on dragDelta
;

【讨论】:

嗨,马特,刚刚收到这个答案。这是一个可能的解决方案,但我喜欢原生 iOS 滚动的感觉,所以我真的很想保留它(而不是试图复制 iOS 做得很好的拖动动量代码)。不过谢谢!【参考方案7】:

在 iOS 开发者库中,Safari 指南中有关于它的解释:

http://developer.apple.com/library/IOs/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

基本上,滚动的事件流是这样的: 触摸/开始拖动(鼠标滚轮事件)-> 平移/移动(无事件)-> 停止(滚动)

因此,没有什么比在平移发生时触发的连续滚动事件更类似于手势结束时的 onScroll 了。

如果您找到了一种可选的方法来实现这一点,请告诉我:)

【讨论】:

恐怕我还没有更深入地了解这个问题,但如果我找到解决方案以及何时找到解决方案,肯定会让大家知道。谢谢大家。

以上是关于使用 -webkit-overflow-scrolling:touch - Safari iOS javascript 事件 (scrollTop / scrollLeft) 时的当前滚动位置的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)