The JavaScript Behind Touch-Friendly Sliders
Nice Article by our friend Nikhil
Feed: CSS-Tricks
Posted on: Friday, June 14, 2013 3:12 AM
Author: Guest Author
Subject: The JavaScript Behind Touch-Friendly Sliders
The following is a guest post by Kevin Foley. Kevin is a developer at Squarespace doing cool stuff with their developer platform, among other things. He was recently working on a swipeable image gallery and he agreed to share some of that work here! A few weeks ago Chris posted a tutorial for creating a Slider with Sliding Background Images. Around the same time I was working on some new swipeable galleries, so Chris suggested I write up a tutorial for how to add swipe support to his slider. Here it is! When creating a swipeable gallery there are two techniques — that I know of — you can choose from. You can animate the scroll position, or move the element using Using TranslateMoving the slider with Using Overflow ScrollOverflow scroll is extremely responsive to the initial touch because it's native to the browser. You don't have to wait for the event listener in JavaScript. But you lose out on all the smoothness of moving elements with translate. For this tutorial we're going to use The HTMLThe HTML in this example is going to differ from Chris's original example. Instead of setting the image as a background image, we're going to set it as an element. That will allow us to move the image to gain that cool panning effect using translate instead of animating the background position.
The CSSFor the most part the CSS is the same as Chris' so I won't rehash how to set up the layout. But there are a few key differences. Instead of simply adding overflow scroll, we need to animate the slides. So for that we're going to use a class to set up the transition and add it with JavaScript when we need it.
IE 10 handles touch events differently than mobile Webkit browsers, like Chrome and Safari. We'll address the Webkit touch events in JavaScript, but in IE10 we can create this entire slider (almost) with nothing but CSS.
Since these properties are probably new to most people (they were to me, too) I'll walk through each one and what it does. -ms-scroll-chainingThe Surface tablet switches browser tabs when you swipe across the page, rendering all swipe events useless for developers. Luckily it's really easy to override that behavior by setting scroll chaining to none on any given element. -ms-scroll-snap-typeWhen set to mandatory, this property overrides the browser's default scrolling behavior and forces a scrollable element to snap to a certain interval. -ms-scroll-snap-points-xThis property sets the intervals the scrollable element will snap to. It accepts two numbers: the first number is the starting point; the second is the snap interval. In this example, each slide is the full width of the parent element, which means the interval should be 100% — i.e. the element will snap to 100%, 200%, 300%, and so on. -ms-overflow-styleThis property lets you hide the scrollbar when you set it to none. The JavaScriptThe first thing we have to do in JavaScript is detect what kind of touch device we're using. IE 10 uses pointer events while Webkit has "touchstart," "touchmove," and "touchend." Since the IE 10 slider is (almost) all in CSS we need to detect that and add a class to the wrapper.
Pretty simple. If you tested the slider at this point it would be a functioning swipeable slideshow. But we still need to add the panning effect on the images.
And that's it for IE 10. Now for the webkit way. This will all be wrapped in the
Then we need to initialize the function and define the events.
Now for the fun stuff that actually makes stuff happen when you swipe the slider. TouchstartOn the iPhone (and most other touch sliders) if you move the slider slowly, just a little bit, it will snap back into its original position. But if you do it quickly it will increment to the next slide. That fast movement is called a flick. And there isn't any native way to test for a flick so we've got to use a little hack. On touchstart we intitialize a setTimeout function and set a variable after a certain amount of time.
We've also got to get the original position of the touch to make out animation work. If you've never done this before, it's a little strange. JavaScript lets you define multitouch events, so you can pass the touches event a number that represents the amount of fingers you're listening for. For this example I'm really only interested in one finger/thumb so in the code sample below that's what the [0] is for.
Before we start moving the slider I'm going to remove the animate class. I know there is no animate class on the elements right now, but we need this for the subsequent slides. We'll add it back to an element on touchend.
TouchmoveThe touchmove event behaves similarly to scroll events in JavaScript. That is, if you do something on scroll it's going to execute a bunch of times while the scroll is occuring. So we're going to get the touchmove position continuously while the finger/thumb is moving.
Then we'll do a quick calculation using the touchstart position we got in the last event and the touchmove position to figure out how to translate the slide.
Then we need to pan the image, like Chris did in the original example. We're going to use the same magic numbers he did.
Now we need to add in some logic to handle edge cases. If you're on the first slide or the last slide this logic will stop the image panning if you're scrolling in the wrong direction (i.e. toward no content). This might not be the best way to handle this, but it works for me right now.
TouchendIn the touchend event we've got to figure out how far the user moved the slide, at what speed, and whether or not that action should increment to the next slide. First we need to see exactly how far the distance of the swipe was. We're going to calculate the absolute value of the distance moved to see if the user swiped.
Now we're going to figure out if the slider should increment. All the other calculations in this example are based on the index variable, so this is the real logic behind the script. It checks if the user swiped the minimum distance to increment the slider, or if the movement was a flick. And if it meets either of those two criteria, which direction did the swipe go in.
Now we add the animate class and set the new translate position.
The ConclusionSo, yea, hooray for IE 10. But seriously, creating swipeable galleries is kind of a pain, considering it's such a common idiom on mobile OS's. And the end result won't be as good as native swiping. But it will be close. Here's the complete demo: Check out this Pen! But you're best bet is checking it out on your touch device here. The JavaScript Behind Touch-Friendly Sliders is a post from CSS-Tricks |
Comments
Post a Comment