Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

ios

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.

like image 889
Jamie G Avatar asked Dec 17 '11 18:12

Jamie G


People also ask

How do I check if a scroll is present?

To check if a scrollbar is present for an element, we can compare the scrollHeight value with its clientHeight value, both are in pixels.

Is scrollTop deprecated?

scrollTop is deprecated in strict mode.

How do I know if my scroll is at the top?

You can check if window. scrollY (the number of pixels the window has scrolled vertically) is equal to 0 . If you want to check if the window has been scrolled to its leftermost, you can check if window. scrollX (the number of pixels the window has scrolled horizontally) is equal to 0 .

Does scrollIntoView trigger scroll event?

scrollIntoView does not trigger mousewheel nor scroll event in Angular. Save this question.


3 Answers

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 :)

like image 132
pixshatterer Avatar answered Oct 20 '22 14:10

pixshatterer


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
};
like image 20
mattsahr Avatar answered Oct 20 '22 14:10

mattsahr


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.

like image 2
spacehelmetboy Avatar answered Oct 20 '22 13:10

spacehelmetboy