简体   繁体   中英

Current scroll position when using -webkit-overflow-scrolling:touch - Safari iOS javascript event (scrollTop / scrollLeft)

I'm using -webkit-overflow-scrolling:touch to make a div with overflow:scroll; scroll smoothly through iOS touch events.

It works brilliantly, except it doesn't seem to update element.scrollTop or element.scrollLeft while it's scrolling. It only updates element.scrollTop / triggers a scroll event when the momentum runs out and it stops.

Does anyone know of a way of finding out its current scroll position and if there's an event I can listen for? I wondered if it can be found through a CSS3 property perhaps? Thanks

Example below showing two attempts:

<!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>

============ UPDATE ============

iOS 8 has sorted this behaviour. Scroll events are now triggered while scrolling.

Note that you'll now have to deal with negative scroll values during the bounce scroll.

In the iOS Developer Library, there is an explanation in the Safari guidelines about it:

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

Basically, the event flow for the scrolling goes like this: touch/start dragging(mousewheel event)-> pan/movement(no events) -> stop(onscroll)

So there is nothing like a continuous event of scrolling being triggered while the pan happens there just an onScroll at the end of the gesture.

If you find an optional way to accomplish that, let me know :)

In a similar situation I am using scrollability.js , which does a really nice job simulating the native scrolling behavior. I'm then listening for the 'scrollability-start' event and monitoring the top/left attributes of the scrolled element. I know it's not ideal, but it's a decent alternative.

This might help. It's a jQuery solution that I'm using to force pagination on IOS side-to-side swipes. It's not exactly the same case as you're working. I'm using the "overflow-scrolling:auto" which does not behave like the "touch" version.

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

I use "overflow-scrolling:auto" because it reacts quicker to the touchend event. Unfortunatley, "overflow-scrolling:touch" does indeed seem to resist javascript and CSS animation while it's in motion. But at least you can get some location information out of it during the scroll.

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

Here is my repository where I've added the callback onScrolling() to let me know when the momentum scrolling animation is occurring in animate() : https://github.com/simpleshadow/iscroll/blob/master/src/iscroll.js

I've made an example app using his suggestion here: http://jsfiddle.net/simpleshadow/wQQEM/22/

@robertlawson86 on Github made this suggestion to help provide an idea on when to grab the position during momentum scrolling. See example and discussion: https://github.com/cubiq/iscroll/issues/183

If it helps, scrollTop and scrollLeft are updated in real-time within the touchmove event handler:

$(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 );
});

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

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

Get the position of a horizontal scroller while srolling ( via css overflow-y:scroll )

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM