7

On my page, I have two panels where the left panel contains a list of items stacked on top of each other and when I click/select one of the items, more information about the selected item is displayed in the right panel. I needed the right panel to be scrollable so added native-like momentum scrolling to this panel as below -

#rightPanel {
    position:absolute;
    top:50px;
    height:400px;
    width:500px;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;  
}

To move through the list of items in the left panel, I have added single finger swipe. It works fine but when I swipe for the next item, the right panel is already scrolled which is not desired. To fix the issue added this small routine and it scrolls the rightPanel content back to top on every swipe but there is a considerable amount of delay which makes it feel like the content is loading slowly.

var scrollStopper = function() {
if ( (swipe == 'right') || (swipe == 'left') )
    document.getElementById("rightPanel").scrollTop = 0;

document.getElementById('rightPanel').addEventListener('scroll', scrollStopper);

Now without momentum scrolling things work as expected. Any ideas on how to scroll right panel back to top on each swipe without causing the delay?

imhere
  • 4,405
  • 7
  • 26
  • 25
  • Check out [HammerJS](http://eightmedia.github.io/hammer.js/). It's a lightweight touch/gestures library that you can use to detect swipes instead of your scroll event (which doesn't fire until momentum runs out). This should get rid of the delay. – Sasha Ko Feb 27 '14 at 17:03

4 Answers4

0

You might get a quicker response from your UI with:

document.getElementById('leftPanel').addEventListener('touchstart', scrollStopper);

It should mean that as soon as the user interacts with the left panel the right panel will snap its scroll.

dijipiji
  • 3,063
  • 1
  • 26
  • 21
0

This happens because in Safari on iOS, the scroll event will fire only at the end of scrolling (this means when you finger finishes a move on screen).

A similar question has been answered here: javascript scroll event for iPhone/iPad?

Alternatively, you could try to use touchSwipe plugin to detect the direction and duration of the swipe and run the function as soon as the swipe has filled the desired treshold.

Here I fire the function after a distance of 10px (probably a higher treshold should be used since this triggers really fast - already on a minimal finger move - but should ilustrate the logic fine):

$(document).swipe(
    {
        // touchSwipe handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch. This is triggered regardless of swipe thresholds.
        swipeStatus: function (event, phase, direction, distance, duration, fingers) 
        {
            // check if we swiped more than 10px to the left
            if (distance > 10 && direction == 'left') {
                document.getElementById("rightPanel").scrollTop = 0;
            } 
            // check if we swiped more than 10px to the right                
            else if (distance > 10 && direction == 'right') 
            {
                document.getElementById("rightPanel").scrollTop = 0;
            }
        }
    }
);

However can't say this is really bulletproof since I've only tested on iPad - I believe it still would need fine tuning and you could always strip the detection down to bare javascript using the same code logic, if using plugins is not an option.

Live sample - also including up and down swipe events:

http://easwee.net/code-samples/touch-swipe-instant/

(changes colors on swipe - red = left, blue = right, green = up, orange = down)

Community
  • 1
  • 1
easwee
  • 15,757
  • 24
  • 60
  • 83
0

To keep the native scrolling active on ios, place the elements you want to scroll in a child element where the parent element has the overflow css.

tnt-rox
  • 5,400
  • 2
  • 38
  • 52
0

If you like the solution I implemented here:

http://proton.orangehilldev.com/documentation.html

The CSS part isn't that complex, you can check it with browser inspector or I can post it later if you can't figure it out on your own. As for JS, this is what I used:

// Disables scroll except for allowed elements that prevent touchmove event propagation
    $(document).on('touchmove', function(event){
        event.preventDefault();
    });
    // Elements which are allowed touchmove event (by stopping event propagation to document)
    $('body').on('touchmove','.scrollable, nav', function(event) {
        event.stopPropagation();
    });
    // Prevents scrollable elements from ever reaching the end of scroll, and thus prevents scroll overflow on ipad
    $('body').on('touchstart','.scrollable', function(event) {
        if (event.currentTarget.scrollTop === 0) {
            event.currentTarget.scrollTop = 1;
        }
        else if (event.currentTarget.scrollHeight === event.currentTarget.scrollTop + event.currentTarget.offsetHeight) {
            event.currentTarget.scrollTop -= 1;
        }
    });
Vexter
  • 1,172
  • 11
  • 12
  • There is no jQuery tag, please only provide solutions for pure JS. – CJT3 Jul 16 '14 at 13:04
  • 1
    jQuery is also written in pure JS :) I have participated in dozen of web projects supporting iOS and there's absolutely no noticable difference in speed when using "pure" JS. I'm also very much against any elitist statements like "I use pure JS only". It's like saying C is slow, I only use Assembly. – Vexter Jul 16 '14 at 14:54
  • 1
    But the OP didn't specify that they were using jQuery, so it isn't a valid response. Especially if their current code is written without it. – CJT3 Jul 16 '14 at 14:55
  • For posterity, I believe that an answer that uses jQuery will be extremely useful as it is such an undeniably utilized library. But I do agree that had the OP asked for pure javascript, we should do our best to provide at least one answer in pure javascript. Who knows, maybe jQuery will make OP life easier. If plain javascript is what you want, check this out: http://youmightnotneedjquery.com/ – Stoutie Sep 02 '14 at 23:19