Horizontal Content Touch Slider: Tablets

Like I said in the previous post: Content Touch Swiper: Phones dedicated for phones. The Horizontal Content Touch Slider: Tablets it’s dedicated for tablets. Uses the same logic and style as the phone one but as you can see bigger thumbs and optimizations for tablets.
Horizontal Content Touch Slider: it’s a touched based slider content, dedicated for tablets. Similar to the horizontal slider you find in App Store or on Google’s search page (the navigation tool bar) of course now they changed it.

The Touch Swiper uses only JavaScript no third library dependencies. It is not a framework or a library. Just a function with a couple of private and public methods. Has been tested on ios devices with different os versions as well on some Android devices.

tochSwiper

You can download it from here. Or fork the repo on Git.
Download

Go to example page.
Example

Let’s talk about the touchSwiper.

I will start with the HTML:

The HTML it’s plain and simple has a main “div” holder, “ul” and “li” list with “a” tags inside (in case you want to go to another page on click)

<div class="h-listing-holder">
    <ul class="h-listing" id="h-listing">
        <li class="listing">
            <a href="javascript:void(0)" class="listing-thumb-link">
                <img src="./images/1.jpg" class="listing-thumb"/>
            </a>
            <h3 class="listing-title">Some Game</h3>
        </li>
    </ul>
</div>

The CSS as well nothing special.

The only interesting thing about the CSS is that the “ul” uses display type “box”. If you have already played with this property you already know what it does. I uses this display type so the content it’s better positioned horizontally as well for the image title. It is supported by the devices and works well.

    .h-listing {
        -webkit-transition: -webkit-transform 300ms ease-in-out;
        -webkit-transform-style: preserve-3d;
        -webkit-backface-visibility: hidden;
        overflow: hidden;
        display: block;
        white-space: nowrap;
        position: relative;
        z-index: 5;
        margin: 0;
        list-style: none;
        padding: 15px 10px;
        display: -webkit-box;
        display: -moz-box;
    }

The transition will make our content to scroll nicely when we swipe so it will not look like a forced swiping. From JavaScript we will add inline style to the “ul” element, and we will use the “translate 3d” CSS property to move the items. Later you will see that as a fallback in the “moveToAction()” JS function if the device/browser doesn’t support “translate” property the slider will move using “margins”.

Keep in mind that some Android devices have a poor support for “translate”property and sometimes the slider might seem to “heavy” but it’s not that noticeable unless you have 100-200 items inside. But works really good with 20-30 scrollable items.

The children inside the “ul” the CSS is straight forward just to make it look better.

Now let’s talk about the main TouchSwiper JS function.

I will cover only the important parts of it. Some methods are self explanatory from the name so I won’t go over them in detail. If you want to find out more just leave a comment and I will go in detail over the method if you want.

The main function called “touchSwiper” it’s triggered on “DOM ready” with the “init “ method. I didn’t made it self executing function but you can do that if you want.

window.onload = function() {
    touchSwiper().init();
}

In the “init” method we check for the device.
Why? Here is the nice part about the Swiper. If the user uses an iOS device with a version higher than 5, the rest of the JavaScript functions will not be executed. From iOS 5 vSafari has good support for “overflow-x:scroll” property. So why not serve to users a “native” look and feel swipe slider? That’s why in the CSS declaration of “ul” you can find the property:

-webkit-backface-visibility: hidden;

This will hide the scrolling bar that iOS creates upon scrolling (the gray bar). And for the user to see that bar it’s not that nice. But using the “backface-visibility:hidden” will do the trick and hide it.

Here is the function that applies the style for iOS 5 and higher.

    //modern slider based on overflow scroll for newer ios versions
    that.touchSwiperModern = function() {
        configs.coverFlowElement = document.getElementsByClassName(configs.boxGames), x, len;
        for ( x = 0, len = configs.coverFlowElement.length; x < len; x++ ) {
            configs.coverFlowElement[x].style.webkitOverflowScrolling = 'touch';
            configs.coverFlowElement[x].style.overflowX = 'scroll';
        }
    };

Let’s get back to the “init” function. If we have a lower version of iOS, or and Android device we can move forward with the actual Swiper. You might ask why not using “overflow-x:scroll” on Android devices as well? Android has a really poor support for “overflow-x:scroll”. Therefore I don’t recommend it. But you can still try it.

In the touchSwipe method we define some default configs that will be later used. Id of the holder, duration of the sliding effect etc. A lot of default configuration :)

Mainly the slider it’s for touch devices, but as you see in the events I have added the mouse support, well just in case.

   events =  [
       {
         start: 'mousedown',
         end: 'mouseup',
         move: 'mousemove',
         leave: 'mouseout'
       },
       {
         start: 'touchstart',
         end: 'touchend',
         move: 'touchmove',
         leave: 'touchend'
       }
  ]

In the main method of the touchSwipe I check for the CSS “transition” support. Most of devices supports it, but an extra check never hurts.

If those properties are supported well, let’s do the swiping. I do some default styleing for the “div”. Basically I apply the transition and translate inline style like I told you above.
The method “setDefaultStyle()” uses a function called “setStyle”. This function does what it says, loops over the properties you send as an object and applies them as inline style.

var setStyle = function(el, properties) {
    for ( var prop in properties ) {
        el.style[prop] = properties[prop];
    }
};

Once the inline style is in place, we start to do the indexing and the offset of the swiped elements. It will start from 0.
What these two methods do? When you swipe, the offset changes of over the items you swipe. That in the end will apply the distance in pixels to the CSS property “translate-3d” that does the movement. “setCurrentIndex()” function it is not used. What it does: in case you want to change the style over the current element in view you can. This function applies an “active” class to the element.

//set the swiped offset
var setCurrentOffset = function(offset) {
    offset = parseInt(offset, 10);
    if (offset != options.currentOffset) {
        options.previousOffset = options.currentOffset;
        options.currentOffset = offset;
    }
};

Let’s move forward. The “initPosition()” function calls the “moveShift()” function which actually moves our content. This function calculates the items inside the “ul” I am using the “children” javascript property to get the “li” children.
In here we calculate the width of each child and send it forward to “doMoveTo()” function. Here if the swipe happend to left or right we will send the offset as an integer, to how much we swiped, to the “moveTo()” function.

 if (options.touchOffset > 0) {
     possibleOffset = options.currentOffset - shift;
 
     if(itemsWidth + possibleOffset > width) {
         setCurrentOffset(possibleOffset);
         moveTo(options.currentOffset);
     } else {
         setCurrentOffset(0 - (itemsWidth - width));
         moveTo(options.currentOffset);
     }
 } else {
   possibleOffset = options.currentOffset + shift;
 
   if( possibleOffset < 0 ) {
      setCurrentOffset(possibleOffset);
      moveTo(options.currentOffset);
   } else {
      setCurrentOffset(0);
      moveTo(options.currentOffset);
   }
}

The “moveTo()” applies a small delay in the animation (this one is in the config of the “touchSwipe()” function), we talked about those configs.

You can change the duration to be faster, slower etc. The “moveTo()” receives the coordinates (offest) that will pass it over to “moveToAction”.
You might wonder why so many functions, moveTo, moveToAction, doMoveTo etc. Well I think it’s better to brake the functionality into small pieces of code (better for performance, easier to maintain and understand). Of course all functions can be combine into one function. But to have a function of “n” lines of code well that at some point will not be pretty.

//move to the give coordinates and apply a delay for animation effect
var moveTo = function(coord, now) {
    var delay = typeof(now) == 'undefined' ? options.duration : 0;
 
    if ( typeof(now) == 'undefined' && typeof(options.onChange) === 'function' && options.hasChanges ) {
        options.onChange(options.previousIndex, options.currentIndex);
    }
    moveToAction(delay, mainContainer, coord, now);
 };

Once we call the “moveToAction()” this will apply the CSS “transition” and “translate” to the “ul” elemet. Here is where the content moves, either to left or right.

var moveToAction = function(delay, el, coord, now) {
    //if there is no animation enabled start set style to the box and end animation
    if (!options.animation) {
        if (delay) {
            startAnimation(el);
             setStyle(el, {
                 margin-left': coord + 'px'
             });
             endAnimation();
        }
        /*if the animation is set start the animation on the box
        set a delay so the animation is visible and apply the moving coordinates */
    } else {
      startAnimation(el);
      var delayTransition = typeof(now) == 'undefined' ? options.duration/1000+'s' : '0';
      if (cssTransitionsSupported) {
          setStyle(el, {
             '-webkit-transition-duration': delayTransition,
             '-moz-transition-duration': delayTransition,
             'transition-duration': delayTransition
          });
          /*if webkit translate is supported move the slider with translate3d css option */
          if ( has3D ) {
            setStyle(el, {
               '-webkit-transform': 'translate3d('+coord+'px,0,0)',
               'transform': 'translate3d('+coord+'px,0,0)'
            });
          /*if the translate3d is not supported then just move the slider with translate*/
          } else {
            setStyle(el, {
               '-webkit-transform': 'translate('+coord+'px,0)',
               '-moz-transform': 'translate('+coord+'px,0)',
               'transform': 'translate('+coord+'px,0)'
            });
          }
     /*if the css3 is not supported do the animation old style with margin-left and apply a delay animation*/
     } else {
         el.setInterval(function(){
            setStyle(el, {
               'margin-left': coord+'px'
            });
            if ( el.style.marginLeft === coord ) {
               endAnimation(el);
            }
         }, delay);
      }
    }
};

If you noticed the “else” statement offers a fallback support. We are going to move the slider using the classic “margin-left”. Just in case the devices doesn’t support transition property.

The “startAnimation” and “endAnimation” functions apply to class “moving” in “startAnimation” and remove the class “moving” in “endAnimation”. This class just sets an z-index that will do some fixes for Android devices.

I think that’s pretty much it. Like I said I am not going to go over all methods because the post will be to boring and to big, and I don’t think even me will have the patience to read such a long post.

One more thing though in “touchSwipeDefault” function you will find:

window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", this, resizeEvent);

I almost forgot about this one. This on the device orientation change will move the swpier “left:postion” or “right:postion” depending on the device rotation. It might be the case that the user scrolls over 5-10 items then he rotates the device. That will recalculate the offset and place the content into the correct position.

I know there were probably some other things that I forgot to mention, but feel free to ask in the comments section and I will gladly help you. Later I will add a dedicated version of “touchSwiper” for tablets.

You can download it from here. Or fork the repo on Git.
Download

Go to example page.
Example

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.