Creating a Mobile Touch Slide Panel with JQuery

by Zack Grossbart on January 28, 2011

Fork me on GitHub

Horizontal Slide View

This is a JavaScript implementation of a mobile style Horizontal Slide View.

Use your finger to drag it left and right to all of the items in the view.

Since this is JavaScript it works on every mobile device with touch support

and

it does a good job with pictures

Each cell of the slider is HTML so you can put anything you want in it

The slider works just like the native application sliders

It snaps each cell into place and supports momentum

Try dragging fast and watch the items fly by

Want to know how it works?

keep reading

This bar is boring on a computer, but it comes alive on a mobile device. Grab your iPad or Android device and take a look.

Drag your finger and the items move with you. They follow your speed and keep your momentum. Play with it a little. I’ll wait.

Get the
source code

The sliding touch panel only shows up on mobile platforms. With a mouse it feels clunky, but sliding with your finger just feels right.

This article shows you how to implement a sliding touch panel in JavaScript. jQuery is the only dependency of the touch slider. The rest is pure JavaScript and HTML. It runs fast, feels natural, and works on every mobile device with touch support.

It all starts with a grid

The sliding panel is a set of div tags: two containers and a div for each cell. The first step is laying them all out in a simple grid.

createSlidePanel: function(/*string*/ gridid, /*int*/ cellWidth, 
                           /*int*/ padding) {
    var x = padding;
    
    $(gridid).each(function() {
        $(this).css({
            'position': 'relative',
            'left': '0px'
        });
        
        $(this).parent().css('overflow', 'hidden');
        $(this).children('.cell').each(function() {
            $(this).css({
                width: cellWidth + 'px',
                height: '90%',
                position: 'absolute',
                left: x + 'px',
                top: padding + 'px'
            });

            x += cellWidth + padding;
        });

Each cell has a fixed width and padding and we lay them out in a single row. We set the overflow property on the container to hidden so we don’t get scroll bars on the grid.

All layout is based in CSS. The grid’s div tag has a position of relative so we can easily move it to the left and right. As the grid moves we adjust the left attribute in the CSS to position the grid. The panel container doesn’t show any overflow so only the cells in the middle are visible.

CSS easily adjusts the positioning with a single property change and the browser renders it quickly. This straightforward layout lets us quickly get to the fun part: touching it.

Make it touchable

There are three important events for touch support:

ontouchstart is called when you first press your finger onto the screen.

ontouchmove is called every time you move your finger on the screen.

ontouchend is when you take your finger off.

The default action for touching and moving in the browser is to scroll. By overriding this behavior we’ll allow the user to scroll our panel without moving the entire window.

This works well for our widget, but it can easily go bad. Overriding the default behavior is often defying the user’s expectations. If you aren’t clear about what’s happening it quickly becomes a bad user experience.

Event handling is a little tricky because we want to make sure the links and any other widgets within the cells still work. We just want the moving events.

The most interesting binding is ontouchend. This one will control if we follow the behavior of the widget that was clicked on or off the panel.

$(gridid).each(function() {
    this.ontouchend = function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        if (touchslider.sliding) {
            touchslider.sliding = false;
            touchslider.touchEnd($(this), e);
            return false;
        } else {
            /*
               We never slid so we can just return true
               and perform the default touch end
             */
            return true;
        }
    };
    ...

The first line binds the event so we can respond to it. Then we have to figure out if we should allow the default behavior or not. This depends if we’re at the end of a slide or just a widget interaction.

We always prevent the default handling of the event. The default is never what we want here. Android will just scroll the screen, but iPads will hover a little magnifying class control that looks broken for our widget.

Touch the screen

The start of the touch is about recording data.

touchStart: function(/*JQuery* elem, /*event*/ e) {
     jsslide.startX = e.targetTouches[0].clientX;
     jsslide.startLeft = jsslide.getLeft(elem);
     jsslide.touchStartTime = new Date().getTime();
     
},

We record the location and the time the touch happened. The location is important since all touches are relative. The time helps us keep track of momentum.

Mobile devices make these panels feel realistic by adding momentum. It gives you the feeling that the panel has weight. If you drag it fast then it keeps going beyond your stopping point. This is the strange physics of mobile momentum.

In the real world force equals mass times acceleration. We need to figure out that force so we know how much extra to let the panel move when you’re not pushing it. Our fake acceleration is the distance you moved multiplied by the time you spent doing it. The start and end time of the touch motion give us that information. Our widget doesn’t have any real mass, so we fake it. That part comes later.

Move your finger

Once the touch is started we need to worry about moving events. The user could move their finger in any direction so we need to handle them both.

touchMove: function(/*JQuery*/ elem, /*event*/ e) {
     if (!touchslider.sliding) {
         elem.parent().addClass('sliding');
     }
     
     touchslider.sliding = true;
     

     if (jsslide.startX > e.targetTouches[0].clientX) {
         /*
          * Sliding to the left
          */
         elem.css("left", "-" + (jsslide.startX - e.targetTouches[0].clientX - 
                                 jsslide.startLeft) + "px");
         jsslide.slidingLeft = true;
     } else {
         /*
          * Sliding to the right
          */
         var left = (e.targetTouches[0].clientX - jsslide.startX + 
                     jsslide.startLeft);
         elem.css('left', left + 'px');
         jsslide.slidingLeft = false;
     }
}

All positions are negative since the panel starts with a left property of zero. Then we figure out what direction it’s moving in based on the current location and the start of the touch. We don’t need any jQuery animations here since the touch is moving fast enough to simulate movement. Adding any extra effects would just slow things down.

Stop touching the screen

The end of the touch is where things get really interesting. There are a number of different ways the touch could end and we have to handle each of them individually.

Using native transitions

At first I created this using JQuery animations. They worked well, but they were a little choppy. Miller Medeiros left an awesome comment about using WebKit transitions so I gave it a try. They worked really well. I restructued the code a little to work with WebKit transitions and it looks great.

We can handle all animations through a single doSlide function. It sets the left property and specifies the transform.

doSlide: function(/*jQuery*/ elem, /*int*/ x, /*string*/ duration) {
     elem.css({
         left: x + 'px',
         '-webkit-transition-property': 'left',
         '-webkit-transition-duration': duration
     });
}

The tranform property is left and we specify a duration for the transform to take. We need to unset these properties once we start the touch again so we don’t wait a long time for every transition while the touch is moving.

Did they drag too far

During the touch moving they could have dragged the bar before the beginning or after the end of the items. We let them do it so the widget seems responsive, but then give them a gentle reminder by sliding the bar back to the right place.

touchEnd: function(/*JQuery*/ elem, /*event*/ e) {
     if (jsslide.getLeft(elem) > 0) {
         /*
          * This means they dragged to the right past the first item
          */
         touchslider.doSlide(elem, 0, '0.5s');
         elem.parent().removeClass('sliding');
         jsslide.startX = null;
     } 

If they drag to the right past the first item then our panel will be left floating with a large space on the left. In that case we’ll slide it back into place.

Dragging left past the last item works in a similar way. We animate the panel back into place so there isn’t any extra space on the right side.

Slide momentum

When the user slides in the middle we need to consider their slide momentum. This tells us how much farther we should push the panel once the touch ends. If they do a short slow drag then the panel shouldn’t move much extra. If they do a long fast drag then we want a large extra slide. The momentum allows the user to easily make big jumps in the slider without having to perform multiple slides.

Calculating the slide momentum is a little tricky. We need to consider the distance of the slide and how long it took.

slideMomentum: function(/*jQuery*/ elem, /*event*/ e) {
     var slideAdjust = (new Date().getTime() - jsslide.touchStartTime) * 10;
     var left = jsslide.getLeft(elem);
     
     var changeX = 12000 * (Math.abs(touchslider.startLeft) - Math.abs(left));
         
     slideAdjust = Math.round(changeX / slideAdjust);
     
     var newLeft = slideAdjust + left;
     
     /*
      * We need to calculate the closest column so we can figure out
      * where to snap the grid to.
      */
     var t = newLeft % touchslider.colWidth;
     
     if ((Math.abs(t)) > ((touchslider.colWidth / 2))) {
         /*
          * Show the next cell
          */
         newLeft -= (touchslider.colWidth - Math.abs(t));
     } else {
         /*
          * Stay on the current cell
          */
         newLeft -= t;
     }
     
     /*
      * Next we'll slide the panel...
      */

To start we need to know how long the slide took. We’ll get this number in milliseconds. Then we need to know the current location of the panel.

Next we need to know how far they slid: the difference between the absolute values of the position when the slide started and the position when it ends. Then we multiply that by a magic number.

The number of milliseconds the user was actively sliding could be very large, easily over 10,000. The amount they moved will be a pretty small number, typically under 1,000. We have to adjust the time to make it feel like the panel has real weight. There’s some solid math behind why I chose 12,000, but in the end it just makes it feel right.

We divide these two numbers and get the slideAdjust value. Then we apply it to the position of the panel depending on the movement to the left or the right. Now we just need to adjust the panel so they match our grid.

Once we’ve moved the panel, if we’re still in the bounds of the grid, then we want to snap the item to the left-hand side of the grid. This is the process of sliding the grid to the left or the right so there is a whole cell showing on the left side.

We calculated the width of each column when we did our first grid layout. Now we figure out of the panel is closer to the start of the cell or the end of it and adjust accordingly.

This is all ridiculous

I’m giving you a little gold star for making it this far . This article is packed full of math and low-level UI programming. This widget does the kind of work you often find in physics engines just so it can show a simple menu. That’s a telltale sign you’re too far out on the bleeding edge.

I could write a native app to do this. IOS and Android both have horizonal slide view widgets. They did the work for me. It would be easier, but native apps lock you in. There’s no way to write a native application for multiple mobile platforms, but you can make your web application look and feel like a native app.

The only solution for cross-platform mobile applications is HTML and JavaScript. That won’t change for at least the next couple of years. Some applications will always require native code, but most of them could be HTML and JavaScript. The environment isn’t as nice, but the cross-platform support is amazing.

Debugging JavaScript on mobile devices

There are some really nice tools for mobile development. XCode is at the top of my list. HTML doesn’t give you anything close to that level of support, but you can get a nice console.

I define a new function named output:

output: function(/*string*/ msg) {
    if (console) {
        console.info(msg);
    }
}

It prints to the console when it’s available. Safari on the iPad and iPhone have options to enable the console under the settings panel. Android does it a little better.

If I plug my Android device into the USB port of my computer and launch the Android SDK Dalvik Debug Monitor I can see a log of everything happening on my Android.

Browser logs are tagged with the word browser. That makes it pretty easy to find them. This interface isn’t pretty, but it works well and I don’t have to switch windows.

This new mobile world is strange, but mobile web applications are a big part of it. They look good, run fast, and aren’t that hard to work with.

Image credits

The images in this slider were provided by the Apple marketing department, the Android marketing department, iStockPhoto, Fir0002, Bff, Gentaur, and doug8888.

  • http://twitter.com/millermedeiros Miller Medeiros

    since you are targeting only webkit browsers there is no need to use jQuery for it.. using css transitions and setting the `-webkit-transform:translate3d(x,y,z)` has a way better performance… (translate3d is hardware accelerated on iOS) check this live example: http://m.sobe.com/sobe-world/ (click on one of the thumbnails)nnIf you have a large amount of items it is a good idea to remove the elements that are not being displayed (on m.sobe I’m not doing it though – the images are always there..)nnPS: I’ve removed the swipe on android since the performance was too bad. (css transforms is only hardware accelerated on iOS for now)nncheers.

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks Miller. That’s a great tip. I’ll need to try that out. I didn’t want to remove the items since I was tuning for a small number of items that move really fast. I’ll keep playing with it and see if I can get it even faster.

  • Pingback: Tweets that mention Creating a Mobile Touch Slide Panel with JQuery -- Topsy.com

  • http://twitter.com/millermedeiros Miller Medeiros

    you can listen for the “webkit transition end” event, like: elm.addEventListener(‘webkitTransitionEnd’, onEndHandlerFn); – you are right about the translate3d, it doesn’t even work on chrome, the way to enable hardware acceleration on iOS and make it to still work on other webkit browsers is to use the regular 2d transform “translateX()” and set “-webkit-transform-style:preserve-3d;” to enable hardware acceleration on iOS.nnanother good note is that on Chrome if you need to update a value constantly (like during the drag) setting the transition duration to zero has better performance than removing it (at least for 2d transforms). nnmore info about CSS transforms and transitions: http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Introduction/Introduction.htmlnncheers.

  • Sunke Premsagar

    i am working on android..ncan you send code of slide moment images in image gallery…n

  • http://www.zackgrossbart.com Zack Grossbart

    I’m not sure what you’re asking. Could you please give me a few details about what you’re looking for.nnThanks,nZack

  • ben

    Hi, thanks for the code its amazing! Definitely the best solution that I’ve found available, and you really helped with the implementation.nnI just had two quick questions. I changed the cell width I believe it was from 150 to 320 and I changed the unit from px to pt, but it seems like the sliding grid is still locking into a grid of about 150. Maybe my description isn’t very good, but when I slide on the iPhone it stops at automatic points about halfway between the later slides. nnAlso I know you covered this in the guide, but I couldn’t completely understand if it could be changed. When I am in the slidecont division I can’t scroll up or down, as my slidecont is almost the entire screen this is very unexpected for the viewer, as you had said, and creates a somewhat negative experience. Is there a way to undo the lock? nnAny help you can give I’d really appreciate! Already do appreciate everything you’ve done.

  • ben

    nevermind about the first question… I messed up your hard work trying to use pt, realized the above grid setting fields couldn’t be based off of pt nnHaven’t been able to figure out about the scrolling though at this point. Loving it now that its locking in though. nnThanks again

  • http://www.zackgrossbart.com Zack Grossbart

    Hello Ben,nnI’m really glad this article was helpful. You can’t scroll up and down because the sliding panel is consuming all of the touch events and telling the browser not to use the normal behavior. If you want to scroll up and down in the iPhone you either have to make your slide panel short enough that there’s some space below it or change the code to make it smarter sbout which touch events to consume and which ones should cause the default behavior. Good luck.nn -Zackn

  • Anonymous

    What about if I have different width?

  • http://www.zackgrossbart.com Zack Grossbart

    The width of the slider will fit your screen or the width of whatever DOM element you put it in. The width of each cell is configurable in the script. nnCheers,nZack

  • B87watanabe

    Hi Zack,nnStill enjoying the slide panel, and have been testing it with some associates on the site I’m building. For myself I have no problem not pressing links as the panels slide, but for some heavier fingered iPhone users they tend to accidentally select links within the cells as they are swiping between panels. nnWould there be a way to make links selectable only when the slide panels is not moving? Maybe something to do with the preventDefault that prevents the scrolling up and down. Might be pretty complicated, but thought I might ask just to see if you had any ideas.nnThanks for all the help.

  • http://www.zackgrossbart.com Zack Grossbart

    Hi,nnI’m really glad the slide panel could help. The panel knows when it is sliding and you can prevent the default behavior of links within the panel. The tricky part is figuring out when the user meant to slide and when they meant click and just wiggled their finger a little bit. nnThe best way to handle this is probably by adding a distance option. That way you would make the user drag their finger a certain distance (5 pixels works pretty well) before you considered it a touch move event. Then you could disable links while you are in that touch move by consuming default events. nnI hope that helps. Good luck.nn -Zack

  • Gina

    I love this, It’s so easy to use, but is there a way that I can start the scroll bar about 75px in from the left?

  • http://www.zackgrossbart.com Zack Grossbart

    You could use CSS to set the position of the sliding grid DIV tag when it starts. Then the script would set the position directly on the element and everything should work. Good luck.

  • Gina

    I had to change it, and I got it to work when I first load the page, but when I swipe it snaps back to the left, is there any way to change that?

  • http://www.zackgrossbart.com Zack Grossbart

    The slider tries to reset back to the left alignment when it moves for the first time. If you want to make the offset work you would need to add it to the code for the slider. This would take a code change, but not a very big one.

  • http://www.referencement-seo-web.fr/ referenceur freelance

    Gu00e9nial, merci beaucoup pour ce tuto.

  • Mike

    I have been working off your slider for a while now and was wondering if you had any input into something else I would like to do.nnFirst, I have made the following changes:nn1) I added another argument to the create slide panel that puts the slider on the center cell by modifying the left offset based on width.nn2) I modified it to allow up and down scrolling, by testing the dx/dy of the touch to guess as to whether a user was trying to go side to side or up and down.nnThere are one thing I plan on doing before I am done:nn1) What would be a good way to modify this script to allow for multiple instances of these sliders on the same page, each with different cell widths? I want to do something where for one slider when sliding, call foobar() {doX(); doY(); DoX();} but for another slider, call foobar() {doF(); DoE();}. I can’t figure out a good way to do this without duplicating the entire thing. This would be simple if I could do abstract classes but I haven’t figured out a good way to do to it with this example.nnAny ideas so to the best way to deal with this? Also, you might want to add your name to the license, as I think that is recommended by Apache.

  • http://www.zackgrossbart.com Zack Grossbart

    Thank you for taking this example so far. I think the right way to make this slider reusable in the way you want is to convert it to be a JQuery plugin. That would let it use local storage instead of object storage and allow different widths for different controls.nnAn easier solution might be to use local storage now without changing much else. There are only a few places in the code where we store locale values so that shouldn’t be too hard. You could make a fork and add that or just generate a patch if you’d like.nnThanks,nZack

  • Deniz

    Thank you for your effort. Is there any update :) n

  • http://www.zackgrossbart.com Zack Grossbart

    This sample is hosted on GitHub. You can find it by following the source code link. The latest code is there.nnnThanks,nnZackn n

  • Sunke Premsagar

    Hi, thanks for the code its amazing

  • Deniz

    Hey nnZackn, Thanks again for this great script. I’ve a question, is there a way to use scroll-y in cell?n

  • http://www.zackgrossbart.com Zack Grossbart

    I’m not sure what you mean about using scroll-y. Are you looking for a touch slider that scrolls vertically instead of horizontally?nnThanks,nZack

  • Dr. med. Wurst

    wow! great thing, but i want to use it for an image gallery consisting of portrait and landscape pictures with an different and varying width?!? is that possible?u00a0

  • http://www.zackgrossbart.com Zack Grossbart

    Right now this script will only work with items that are all the same width. It wouldn’t be too hard to change that, but it would require a change to the code.

  • Dr. med. Wurst

    u00a0what a pity, then I’ll have to wait for V1.1 :-(

  • yannick

    u00a0Hey, Great slider.nnI have a question: is it possible to get rid of the snapping effect? i’d like to make it slide with the momentum but slow down to stop instead of snapping to the next images. Can you help me out here, i’m no jquery genius so if you can make it simple i would appreciate. thanks so much! keep it upnnYannick

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for trying this out. u00a0 Getting rid of the snapping effect is pretty easy.u00a0 Take a look at the source code on GitHub.u00a0 The touchEnd function on line 151 gets called when the user picks their finger up after sliding.u00a0 nnThere are two places in there where we call the touchslider.doSlide function.u00a0 That function is the one that causes the grid to snap to show a whole section.u00a0 Just comment out those two lines and the snapping should stop.nnGood luck,nZack

  • maryisbusy

    u00a0this is just what i was looking for! awesome work! I notice you have all the cell with their own ID. how could i make a link that would scroll nicely to an href=”#thatID”?

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for checking it out.u00a0 I haven’t really tried, but I think something like this would work:nnClick me to slidennThat says find the element that is the touch slider, move it to the left until the element thatID is showing, and make the slide animate for 2 seconds.u00a0 I haven’t tried it, but I think that should work.u00a0 nnLet us know how it goes.nnGood luck,nZack

  • Deniz

    Zack, are you using this script on a live mobile website? Is there a way to see a few live examples?

  • http://www.zackgrossbart.com Zack Grossbart

    This article is a live example of this script.u00a0 The sample at the top will slide on your mobile device.u00a0 There is also a stand alone example at http://www.zackgrossbart.com/extras/touchslider.

  • Anonymous

    Great script!u00a0 I’m trying to figure out how to get this to work vertically rather than horizontally.u00a0 I’m close but seem to be missing something…any suggestions would be greatly appreciated!

  • http://www.zackgrossbart.com Zack Grossbart

    You’d have to make a number of small changes to make this work vertically. How far have you gone? Can you share a little code?

  • Dan Moore

    Thanks for the great code.u00a0 One feature I was looking for was deferred loading of images.u00a0 So that you the page doesn’t load all images at once, but just as they are scrolling into view (or perhaps when they are next in line).u00a0 nnI’m afraid I don’t know enough about this code to know if this is easy, difficult or impossible.u00a0 Could you venture a guess?nnThanks,nDan

  • http://www.zackgrossbart.com Zack Grossbart

    Right now every image in the slider is just like an image anywhere on the page. It loads when the page loads. You can speed up that loading by adding all of the images to a single sprite.nnThe other option is to change the script to add the image only when the load into view. This should be possible, but I can’t see a way to do it very well generically. Right now the script doesn’t know if any cell even has an image at all. You would have to pass the image to the script in some fashion so the script could handle making it work.nnSo the short answer is that it would be possible, but it would take some coding.nnGood luck,nZack

  • Fertpolin

    this isn’t working :(, do you have any solution?

  • http://www.zackgrossbart.com Zack Grossbart

    Can you give me a few more details? What isn’t working?u00a0 Are you trying to edit this code or just use it as it? Are you getting any errors?nnThanks,nZack

  • shai galili

    greate lightweight stuff, I think of using it.ndidm’t you forgot the 3 little dots that comes below the panel?nsee “Carousel” underu00a0http://dev.sencha.com/deploy/touch/examples/kitchensink/

  • http://www.zackgrossbart.com Zack Grossbart

    That would be a great feature for the next version.

  • Mgunnels

    Hi,

    how are you controlling the width of the cells? I would like to increase the width of them.

    thanks for any help.

  • http://www.zackgrossbart.com Zack Grossbart

    The width of each cell is controlled at the end of touchslider.js.  The line looks like this:

       
    touchslider.createSlidePanel(‘#slidebar’, 200, 15);The first argument is the ID of the slider element, the second is the width of the cells, and third is the padding. Good luck,Zack

  • http://www.facebook.com/crazyfretz Glenn Mason

    You’re a genius! thank you so much, I’ve been looking for this kinda mathematical function for ages.

  • Z Mayel

    Thank you for this tool, i have tried but i become this error message for javascript : 

    $ is not defined in the touchslider.js line 272 , kann you help me please ?

  • http://www.zackgrossbart.com Zack Grossbart

    This error indicates that the script can’t find JQuery. I would double-check that the JQuery JavaScript files are referenced correctly from your HTML file and loaded correctly from the server.

  • Z Mayel

    I have found the error, i work with jquery Mobile and asp.net and it have a conflict  between scripts . 
    Thanks for your answear 

  • Sumantra Dey

    How can I control the swipe sensitivity of this fantastic slider.For example if the total
    swipe distance is 100px  then image changes each  5px.

  • http://www.zackgrossbart.com Zack Grossbart

    The touch slider supports momentum which means it will start sliding faster if you move your finger faster.  This allows the user to scroll a long distance with a short movement. 

    There isn’t any parametrized way to control how we calculate the momentum, but you can change the algorithm if you’re feeling brave.  The function to look at is slideMomentum in touchslider.js.

    Good luck and please let us know how it goes.

    Thanks,
    Zack

  • Jonathan

    Hi, I would like to create a multi row…so there will be 3-4 rows instead of 1….May I know where can I modify it ? Thanks….

  • Z Mayel

    Hi, 

    i want to make the cells selectable. kann you help me please ?

    i my project it will be a touch image galarie and from there, the user can select an image 

    thanks

  • http://www.zackgrossbart.com Zack Grossbart

    You could add a multi-row layout with JavaScript in the touchslider.js. You might want to combine this with another article on this site: Create Your Own Sliding Resizable Grid. You’ll also have to change the logic in the touch slider to determine the positioning differently since the the width of the control will change based on the rows.

    This could make your logic much easier. If you always want to wrap at the same number of columns then you could hard-code a width and simply handle the times where there aren’t a full row as a special case. It would also make the code faster.

    This should be pretty straight forward, but it does require some programming and a familiarity with JavaScript. Good luck and please let us know how it goes.

  • http://www.zackgrossbart.com Zack Grossbart

    Each cell is just a DIV tag. You can put anything you want in each one. If you wanted to combine this with some JavaScript to handle the selections it should work well. Please let us know how it goes.

    Good luck,
    Zack

  • Ryanklu

    I used the code exactly how you have it spelled out below and am not able to get it to slide to my 7th cell. The url to my test is http://www.hrinoc.com/jstouchslide/test.htm, I have been trying to use this code for a iPad WebApp project. I think you will be able to see my code pretty clearly, I have just modified a couple things from your original file.

    Thanks again

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for using this code. Your event looks like this:

    touchslider.doSlide($(‘#slideBar’), ‘-’ + touchslide.getLeft(‘#seven’), ’2s’); return false;

    It looks like you have a small typo. Try this:

    touchslider.doSlide($(‘#slideBar’), ‘-’ + touchslider.getLeft(‘#seven’), ’2s’); return false;

    Good luck,
    Zack

  • Ryanklu

    Hi Zack,

    So I implemented the new code with the ‘touchslider’ spelled correctly and still nothing. The test is still at http://www.hrinoc.com/jstouchslide/test.htm.

    Thanks again for the quick response and great script and documentation.

    ~Ryan

  • http://www.zackgrossbart.com Zack Grossbart

    There were a couple of other issues. The first is that your onclick needs to look like this:

    onclick=”touchslider.doSlide($(‘#slidebar’), ‘-’ + touchslider.getLeft($(‘#seven’)), ’2s’); return false;”

    Note that the ID of slidebar is case sensitive and that the second part needs to be a JQuery object. The other change is to the CSS. You need to change this:

    #slidecont {
    overflow: auto;
    position: relative;
    }

    #slidebar {
    overflow: visible;
    position: relative;
    }

    Those changes got everything to work for me. Please let me know how it goes.

    Thanks,
    Zack

  • Ryanklu

    Zack your the man! I got it all to work, thanks for your quick responses I will make sure to send you a link to our webapp project when its finished. Thanks again.

    ~Ryan Lu

  • Pritham

    Hi, I tried integrating this script into a jsp page. It works fine only on mozilla but not on safari or opera. Can you please let me know how to go about solving this? Is this a problem with my css.

  • http://www.zackgrossbart.com Zack Grossbart

    I haven’t tried this script on Opera, but it works well in Safari for me. Does the sample in the article work for you on those browsers? When it doesn’t work, what happens?

    Thanks,
    Zack

  • Pritham

    I tested this sample on safari and opera, it works good. In case of my jsp page, the cell and the div totally disappears from these browsers but it comes alive in mozilla. The same is the case when I am using jquery mobile ui page swipe. It is alive on all browsers but not on mozilla. It may be a problem since I am building a mobile optimized website and using meta tags and jquery mobile ui. I’ll check this one and let you know how it goes.

    Thanks,Pritham

  • Clark

    Great plug-in.  Any thoughts on how to allow the default vertical scrolling behavior?  I want users to be able to flip left and right through the slider, but if they slide vertically, I want the page to scroll as normal (important for iPad and iPhone as often the slider takes up much of the screen)

  • http://www.zackgrossbart.com Zack Grossbart

    Right now the slider consumes all touch events. You could enable vertical scrolling by ignoring touches which go up and down. Normally you would handle this with a threshold. Something like, “if the touch goes more than 20 pixels up or down then don’t consume it.”

    This shouldn’t be too hard to add, but you would have to change some of the JavaScript.

    Good luck,
    Zack

  • Anonymous

    Is there a way to get this make this draggable with a mouse too, rather than having to use the scroll bar? Thanks

  • http://www.zackgrossbart.com Zack Grossbart

    You could add JavaScript to support dragging with the mouse, but this script doesn’t support that right now.

  • Chris Cullari

    I just ran into a situation where when the contents of the slider are not as wide as the width of the slider itself, the left slide breaks. It never snaps back to the grid location, and if you slide fast enough, you can actually loose the contents of the slider. As such, I had to make an update to the script to accommodate for this scenario. Specifically the touchEnd function as listed here:

    else if ((Math.abs(touchslider.getLeft(elem)) + elem.parent().width()) > touchslider.width) {             /*              * This means they dragged to the left past the last item              */ if((touchslider.width – elem.parent().width()) > 0) { touchslider.doSlide(elem, ‘-’ + (touchslider.width – elem.parent().width()), ’2s’);                          } else { touchslider.doSlide(elem, 0, ’2s’); }               elem.parent().removeClass(‘sliding’);             touchslider.startX = null;           }I figured that it would be worth bringing up as others might experience the same issue.

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for the update.  This is a case I hadn’t testing with this script.  It is probably a relatively simple edge case to handle.

    Thanks,
    Zack

  • Nestor Aleman

    Hi

    Brilliant!!

    How can I have different pages with different slide panels? My aim is to load on screen a different slide panels depending of user’s input.

    Thanks

  • http://www.zackgrossbart.com Zack Grossbart

    The touchslider is created with a simple JavaScript call like this:

    touchslider.createSlidePanel(‘#slidebar’, 200, 15);

    You can call this multiple times with different IDs in your page. I think it should work, but I haven’t tried it. Please let us know how it goes.

    Thanks,
    Zack

  • Nestor Aleman

    Hi Zack

    I have tried, first using:

    touchslider.createSlidePanel(‘#slidebar’, 200, 15);
    touchslider.createSlidePanel(‘#otherPage’, 200, 15);

    and also creating another touchslider function (touchsliderOther.js) and calling:

    touchsliderOther.createSlidePanel(‘#otherPage’, 200, 15);

    And neither works, maybe I am doing something wrong …

    Thanks for the quick reply!!

    Cheers,

    Nestor

  • http://www.zackgrossbart.com Zack Grossbart

    Do you have Firebug installed? Do you see any errors in the console when you try to make this work?

  • Nestor Aleman

    Yes Zack, I do

    And no error highlighted in the console …

    Weird, isn’t it?

  • http://www.zackgrossbart.com Zack Grossbart

    When JQuery applications fail without errors it often means you didn’t get the elements you expected. Any chance you have duplicate IDs in your page or incorrect classes?

  • Nestor Aleman

    Sure Zack

    That was the first thing I did, looking for duplicated ID’s or incorrect classes, but after 9 hours working maybe I could have missed something jeje. I will check again tomorrow and let you know.

    Thanks a lot anyway

    Cheers,

    Nestor

  • Nestor Aleman

    Hi Zack

    I was trying to create various pages within the same html document and seems that your plugin doesn’t work when trying to call it multiple times within the same document.

    Finally I have created different html document for each page and I now can switch dinamically from one Slidepanel to another by linking to different URL’s.

    Hope you can understand my solution.

    Thanks very much indeed for you help

    Regards,

    Nestor

  • http://www.zackgrossbart.com Zack Grossbart

    I’m sorry you had so much trouble with it.  It should work multiple times in the same page, but I haven’t done much testing in that configuration.  I’ll try to find some time to look at that pretty soon.

    Thanks,
    Zack

  • Mike M

    At some point I will post my modifications to github, but maybe this will help for now:

    I modified the structure of the touch slider to be “re-useable” by taking advantage of Object.create() which is available in EMCA 5.  It doesn’t support older older browsers, but there are ways to hack around that (by creating your own Object.create()). 

    Basically you limit the touch slider to all the functions that will be constant to all sliders.  So things like touchStart, touchEnd, slideMomentum, doslide, touchMove, and getLeft will be contained in a sliders object that uses javascript literal notation.  You also have to change all references of “touch slider” to “this” and work around issues where this=jquery this and not the actual object like in query loops and stuff.

    Then you create another object, like:

    var productItemSlider = {  createSlidePanel: {    value: function(/*string*/ gridid) {…}  };

    That way you can do all sorts of customization in the createSliderPanel for each specific slider type.  Then when you want to use the slider, you do something like:

      var parentSlider = Object.create(sliders,promotionalItemSlider);  parentSlider.createSlidePanel(“#promotionslider”);

    I also added parameters to makeTouchable called postTouchMove and postTouchEnd.  You can then implement these in your slider sub class, and in makeTouchable I do something like this:
    var SliderObject = this;
        if(postTouchMove !== null){      postTouchMoveApply = function(){        postTouchMove.apply(sliderObject,arguments);      };    }    if(postTouchEnd !== null){      postTouchEndApply = function(){        postTouchEnd.apply(sliderObject,arguments);      };    }

    then I pass in postTouchApply and postTouchEnd to touchEnd and TouchMove.  That way I can have it do specific things to the slider after moving or ending, for each type of slider.

  • http://www.zackgrossbart.com Zack Grossbart

    This sounds like a really interesting way to go.  I’d love to see a patch when you have one.

  • Mike M

    It took a lot of trial and error to get everything to work but its been working great.  I can create many different types of sliders, for example a slider that works like a iPhone paged UIScrollView.  By adding the call backs i can have it to things like update the page control element to the correct page when its done sliding.

    I created another example where it it “zooms” in on the center cell, but adding a postTouchMove function that calculates the center cell on each move and compares it to one that I have stored in the object.  If its different, it can zoom the new one and unzoom the old one.

    And in both cases, by calling Object.create(), it creates a new instance of each one so I can create multiple sliders of the same or different types on the same page.  And because most of the functions are shared, I don’t have to duplicate lots of javascript.

    I really hope to put something up soon.  I created the branch in github a while ago I just haven’t had time to generalize what I created for an example.

  • http://www.zackgrossbart.com Zack Grossbart

    That sounds so awesome. Please send us a link whenever you have one.

  • http://twitter.com/anujwalia26 Anuj walia

    it worked great , the effect is awsum  when i tested in my iphone but according to my requirements i want to make it vertical , sliding from top to bottom and visa versa . Can you help me with that Zack ? It will be of great help.
    Thankx in advance

  • http://www.zackgrossbart.com Zack Grossbart

    Hello Anuj,

    This script does not support vertical sliding now. A few other people have asked for this and it wouldn’t be too tough to add it.

    -Zack

  • Pilgoo

    Thank you from Korea. 
    Though I’m not a programmer but I tried this source and it worked. I tested this with my personal web-site which is still under development. That’s really what I want.  
    http://www.fairedu.com/main/index.html

  • SPJohnston

    Hey Zack, great work on the script.

    I’m having a bit of an issue though with trying to implement what I need, which is the slider to automatically scroll to the next image every 5 seconds and loop when it gets to the end. As soon as you touch or drag on the slider though, I want it to pause the autoslider until I release my finger. This way it’s always auto scrolling for normal broswers but if your on a touch device you can scroll to whatever image you please and as soon as you stop it will start the autscroll again from that new position.

    I had another script I tried to use but it seems to be doing something weird and ends up leaving a big gap at the end of the images. Here is the script I’m trying to use with your script.  I tried adding your touch event handler to this script but it still messed up when using together. I think it’s the fact that it gets the total width of all the cells. 

    $(document).ready(function(){    /* This code is executed after the DOM has been completely loaded */        var totWidth=0;    var positions = new Array();        $(‘#lightHero cell’).each(function(i){                /* Traverse through all the slides and store their accumulative widths in totWidth */                positions[i]= totWidth;        totWidth += $(this).width();                /* The positions array contains each slide’s commulutative offset from the left part of the container */                if(!$(this).width())        {            alert(“Please, fill in width & height for all your images!”);            return false;        }            });        $(‘#lightHero .cell’).width(totWidth);    /* Change the cotnainer div’s width to the exact width of all the slides combined */    $(‘#controls a’).click(function(e,keepScroll){            /* On a thumbnail click */            $(‘#controls a’).removeClass(‘selected’).addClass(‘off’);            $(this).addClass(‘selected’);                        var pos = $(this).prevAll(‘#controls a’).length;                        $(‘#lightHero .cell’).stop().animate({marginLeft:-positions[pos]+’px’},750);            /* Start the sliding animation */                        e.preventDefault();            /* Prevent the default action of the link */                                    // Stopping the auto-advance if an icon has been clicked:            if(!keepScroll) clearInterval(itvl);    });        $(‘#controls a:first’).addClass(‘selected’).siblings().addClass(‘off’);    /* On page load, mark the first thumbnail as active */                //Enabling auto-advance.         var current=1;    function autoAdvance() {        if(current==-1) return false;                // [true] will be passed as the keepScroll parameter of the click function above        $(‘#controls a’).eq(current%$(‘#controls a’).length).trigger(‘click’,[true]);         current++;    }    // The number of seconds that the slider will auto-advance in:        var changeEvery = 5;    var itvl = setInterval(function(){autoAdvance()},changeEvery*1000); });

  • http://www.zackgrossbart.com Zack Grossbart

    Thank you for using this script.  I’m not sure how to help you with this one. 

    Making the slider scroll to a specific cell is pretty easy and you can make it loop by scrolling back to the first cell when you hit the end.

    I’m not sure exactly what your code is trying to do.  If you have it running somewhere I can take a look.

    Thanks,
    Zack

  • SPJohnston

    Hey Zack and thanks for responding.

    Yeah I have a test page up here: 
    http://www.shaunpauljohnston/TESTER/iphoneTest1.html

    and

    http://www.shaunpauljohnston/TESTER/iphoneTest2.html

    On teh first page I have it just auto scrolling and it works great, no touch controls though. So adding your script as seen in iphoneTest2, the autoscroll works but when it gets to the end it just shows blanks for about 15 seconds then the slider starts again.

    All I’m looking to do is have the slider autscroll as standard and when you use touch it takes over. Once you stop touching the autoscroll would start again.

  • SPJohnston

    Just to clarify, I am a total novice with js. I can normally work bits and bobs out with code but I’m clueless here.

    Initially I thought I could just add a touch gesture to scroll in the current code but when i couldn’t work that out, I stumbled upon your solution which is fantastic for the touch controls but it just seems to have some conflict with the problem I mentioned above.

    cheers,
    Shaun-Paul

  • http://www.zackgrossbart.com Zack Grossbart

    Did you miss the top level domain in your test page?  http://www.shaunpauljohnston isn’t a valid URL.

    Thanks,
    Zack

  • SPJohnston
  • SPJohnston

    OK I’ve found out a little more. 

    lets say it’s autoscrolled to the 5th slide and I decide to start using touch to change the slide, Once I scroll to the last slide it will go past it and load up a blank slide. If I wait for a while the slider will reset and I can see it autoscroll to the 5th image then it goes blank from there again. 

    I counted how long it took to reset back to the start of the slider and it seems it was 25 seconds (the 5 slides after where I started touch scrolling). I check on starting on later slides and it’s doing the same, whatever slide I started to use touch controls on, it will go blank from there.

    Does that make any sense? I know in the script for autoscrolling, it’s determining the total width and the onclick event for the hidden controls checked what slide your on, so I’m assuming it’s something to do with that. It’s finding that it’s on say position 1200 from the left, the 5th slide. Why it’s not showing the slides once it resets or allows me to scroll past the end of the images I don’t know.

  • http://www.zackgrossbart.com Zack Grossbart

    I would try calling the doSlide function every time you want to slide instead of just moving the slide panel.

  • SPJohnston

    When you say use the doSlide function, how would I use that?

    Would I leave my original script as it so it would still be getting the max width and autoscrolling?

    Or would I need to add a doSlide function in there somewhere replacing something else or is it something I need to add to your script?

    Sorry for being a pain, what I thought was a simple issue has now kept me up for 2 days with no sleep as I hate leaving something and not being able to figure it out. 

    I appreciate you taken the time to answer my questions,
    Shaun-Paul

  • http://www.zackgrossbart.com Zack Grossbart

    In general I would use one script instead of two.  You can do this all with this script and a little more code so I would do that.  Whenever your timer triggers call the touchslider.doSlide function instead of just moving the slide panel.

  • SPJohnston

    Hey Zack. I left a proper comment but I think it messed up.

    Basically i was just saying I can’t work out what to do based on your last few replies. I’m not good enough with js/jquery to write code from scratch unfortunately. Trying to learn bits and bobs to try understand but struggling.

    I’d rather just use one script as you say, preferably yours. What’s bugging me is both work perfectly on their own but as soon as I try use both it messes up. I understand what your saying about using  a single script but I really don’t understand how to implement autoscroll on your script or how to do the doSlide function you mentioned.

    I’ll keep reading the code and trying things out but I feel like I’m just going round in circles and learning nothing. 

    Well hopefully you’ll add such features to this script if you ever update it, if not thanks for the help and advice anyway, it’s appreciated that you took time to try help me at least lol.

    Shaun-Paul

  • http://www.zackgrossbart.com Zack Grossbart

    Hello Shaun-Paul,

    You could make it auto-scroll with some code like this:
    var shouldCancel = false;

    var cells = $(‘#slidebar > div’);
    var index = 0;

    function doScroll() {
        setTimeout(function() {       
            if (index < cells.length) {
                index++;
            } else {
                index = 0;
            }
           
            touchslider.doSlide($('#slideBar'), '-' + touchslider.getLeft(cells.eq(index)), '2s');

            if (!shouldCancel) {
                doScroll();
            }
        }, 5000);
    }

    doScroll();

    However, this is just the idea and I haven't run this code.  You're basically running into two scripts which weren't designed to work together.  This might be a good time to think about hiring someone to write a little script for you.

    Good luck,
    Zack

  • SPJohnston

    Hey Zack.

    Thanks for trying out some code. I tried it but not sure I’m doing it correct, not sure where it’s to go actually,is it to go in your script at the $(document).ready(function){}); section or above that in the actual main script.  

    Or is it to go in the other script I have replacing the timer function there?

    I wasn’t sure about this line either: var cells = $(‘#slidebar > div’); 

    I know > means greater than but I’m not sure how it’s being used here. Maybe my head is hurting from lack of sleep or something but I’m sure I’ll figure it out. 

    regarding hiring someone, well your probably correct I should, however I’m unemployed at the moment, trying to create a website for my brother who’s made his first IOS game but it’s not done that well, I think down to being a bit of a niche title, so I wanted to help him out by making a better website to help try promote his game or any future ones. Money right now is non-existent until I find some work. Being a professional actor who’s currently out of work doesn’t help the situation either.

    Cheers,
    Shaun-Paul

    PS. I’ll make sure to show my appreciation for all your help, whether I post something on my blog or just Google+1 your page or something. Doesn’t do much but just something to say thanks.

  • http://www.zackgrossbart.com Zack Grossbart

    Hi Shaun-Paul,

    You should put this code in the top of the document.ready function. 

    The greater than symbol in the selector indicates that we’re looking for child elements.  In this case we are selecting all DIV tags which are children of the element with the ID slidebar.

    I’m sorry to hear about your current job situation.  Good luck finding something soon. 

    Thanks for the offer to +1 or post.  Tweets are always easy and nice.

    Thanks,
    Zack

  • Shaun-Paul

    Hey Zack.

    Okay another day another set of trial and errors. I used your code and added it to the Document ready function at the bottom. Using it as you wrote it wouldn’t work, but I noticed what I think was anyhow on your original code where you set the ID to #slidebar >div. I changed this to #slidebar .cell, what I have my divs class set to.

    Again this didn’t work, so I added the setInterval code from my other script below which is:

    var Intv = setInterval(function({doScript}),5000);

    Now I got the slide to autoscroll, however a new issue arose. The slider takes 10 seconds to slide to the second div. I know this is because there are two times of 5000, one for my setInterval and one for your setTimeout.

    The second issue was that after it slid in the second slide, the next slideTransition jumped two slides instead of only one. The next slide jumped 3 slides and so on.

    Not sure if you know what’s causing that, but one thing I’m really unclear about is this. If I remove my setInterval code then I don understand how to get the code you wrote to initialise. I assume that’s why nothing happens when I remove my code, because it’s not being triggered! S my question is this, how do I get it to run when the page loads without adding an onLoad to the body tag?

    I’m in the process of reading through Head First JavaScript so hopefully this will be more clear as time progresses ;-)

    Cheers once again,
    Shaun-Paul

  • SPJohnston

    LOL being the moron that I am sometimes, probably due to a lack of sleep I realise where I was making some mistake with initialising the script. That’s fixed now and it’s loading and working.

    If you take a look at the page on a desktop PC, only the first image shows, then when it slides after 5 seconds all you see is the background, no more images, not sure why?

    The second issue is that on the IOS device, it scrolls perfectly now but stops when it gets to the end of all the images. Another thing, when I scroll on the IOS device, lets say I scroll two images from where it’s currently at, when the autoscroll kicks back in, it will go back two slides back to the slide before I started using touch to change image. If that makes sense.

    So I need to fix the desktop browser issue not sowing the other slides, I need to restart the image scroller when it reaches the end of the images, I take it I use some loop method here, sure I can find something, maybe make it circular or something, sure that’s something I read last night. And finally I need to fix it so if I scroll using touch, the autoscroll continues from that point, not the point where I was before the touch event.

    Cheers Zack, seriously. It’s nice just to have someone on here helping me out. Maybe if I land a decent acting gig, if I’m on a pc or something, I’ll have it so you can see your website ;-)

    Shaun-Paul

  • SPJohnston

    I’ve tweeted and +1′d your website :)

    By the way what does this do? 
    if (!shouldCancel) {            doScroll();        }

    I can kind of understand that it’s to do with how the scroll works but I’m confused by the var that’s set for it: 

    var shouldCancel = false;

    Maybe I’m clueless but it seems like that’s making two negative/false values. shouldCancel is false and the code then says, if it’s not shouldCancel/false then doScroll, what does it do if I am way off here?

    Any idea about why the code is acting weird on desktop browsers where it’s only showing 1 image then nothing? I’m still trying to find a loop for the scroll, making slow progress though, I also have it under your one script now so at least that’s a positive :)

  • SPJohnston

    OK I got the loop working by adding the following:

    if (index == cells.length) { index = 0; }

    That seems to do the trick for the loop part, now I just need to work out the other parts, the PC issue and the way to have it so if I touch-scroll then it recognises it and when I stop touch-scrolling it carries on from that slide I scrolled to, not the one where it was at before the touch event.

    Woohoo, I feel like it’s finally getting there :)

  • http://www.zackgrossbart.com Zack Grossbart

    This code is using a timer to keep things looping forever. That variable gives you a way to stop the loop if you need to.

  • SPJohnston

    Hey Zack, just thought I’d update with my progress on the slider.

    So I figured out the problem with showing on desktop browsers. I think because I added your code to an existing div, I wasn’t setting the width correctly on the right element, so I now fixed it and it’s scrolling correctly on desktops. 

    It seems I had to add the total width to my css for #slidebar, so now it’s set to 2200px, all my divs combined and it seems to work fine.

    So on desktops it’s scrolling and looping at the end when the if (index == cells.length){index = 0}; is called, this also works n IOS devices fine so no issues n that sense and what I wanted. 

    The only thing I’d like to have is for the auto-scroll to take into account when I have used the touch controls and update the position s when it starts auto-scrolling it does so from that point. As it is now, if I scroll say a couple of images using my finger, the auto-scroll will go back those couple of cells when it kicks back in again after I stop the touch event.

    Also regarding my loop addition, is there a better way to set this? As it is it gets to the end of the images then scrolls all the way back through the images so you see them all again before starting to scroll from the beginning again. I read something about setting “wrap : true”, but i couldn’t get this to work. I’d prefer it so the slider loops but when it gets to the end it just carries on seamlessly.

    Cheers,
    Shaun-Paul

  • SPJohnston

    Hi Zack, got a new question for you.

    I was looking through the comments and found the idea of having a link that you could click on and it would take you to that specific div. So you would touch on an div with ID say #image1 and it could take you to another div with an ID of #image5.

    Anyhoo I was wondering if I can do it on the actual slides themselves, do if I just tap on an image it could take me to another div, working like a native app. I came up with the following after testing around but not sure why it won’t work.

    ================= Javascript

    function (){ touchslider.touchEnd($(‘#image1′), function(){ touchslider.doSlide($(‘#slideBar’), ‘-’ + touchslider.getLeft(‘#image5′), ’2s’); });}

    ================= HTML
                                                                     

    I’m going to assume it’s possibly because it’s on the main div for that image/slide, if I added an element into that div and used that ID instead as the initial ID, then I could do it?

  • http://www.zackgrossbart.com Zack Grossbart

    You can add any content to DIVs in the slider and you can make any DIV, A, or any other tag which gets click events move the calendar to a specific cell.

  • SPJohnston

    Hey Zack.So great progress on the slider, it’s actually looking and working fantastic now. You can check it out here: http://www.shaunpauljohnston.com/TESTER/iphoneTest2.htmlIt’s up temporarily just to test it out so none of the other links etc work at the moment and eventually I’ll have touchable links in each slide.What I am stuck on though is when using touch, how can I get the script to update the index based on what slide it’s ended on when the touch event ends? Right now I can do it on any links to slides as in using a click event and setting the index to that slides index, but when dragging with a finger on IOS devices it will scroll to the correct div as intended but it doesn’t set the correct index for that particular cell. So if I drag to the 5th cell ie. (index = 6) it doesn’t seem to set the touch event to that index because it will just scroll back to where it was before I did the touch event.Sorry if I was asking loads of questions before but you’ve been great so thanks,Shaun-Paul

  • SPJohnston

    Hey Zack, how you doing?

    I have something that might be quite cool to add to the code but unsure how to implement it, maybe you have  better idea.

    You know when you record your computer screen on a mac, you can have it show your clicks by showing a little circle mark where the person has clicked, basically just a visual cue for people watching the recording. Well I’m wondering if that can be implemented to the touch events when clicking on cells or anything within them.

    I tried creating a custom cursor and have it change on mousedown then change back on mouseup, but it seems any time I added the mouseup it would break the effect. So if I only used mousedown, I could get it to show the new cursor, but that defeats the point as it means the cursor is now always that state. I can’t do it with an onclick handler either because again that changes it to the new cursor and not back again.

    I’m trying to avoid adding it to the elements I the html and just do it through the javascript but I just can’t work it out. However I think by adding it, it would add a real nice visual element to the slider. On a pc any time you clicked you would see the new cursor for a short period before it resets and on IOS devices it would be the same but would stay as long as you were touching the slider area.

    Any update on that other issue with the slider I mentioned previously, where it wouldn’t update the index value if I slide the slider using my finger?

    Cheers,
    Shaun-Paul

    PS. What do yo think of the slider on the page I linked before, looks pretty decent doesn’t it?

  • http://www.zackgrossbart.com Zack Grossbart

    Hello Shain-Paul,

    I haven’t had much chance to look at your site yet.  It all looks generally good.

    I’ve looked into dots or some other indicator to show how much more you have to scroll.  It would be a nice feature, but I haven’t had time to add it. 

    I’m glad it is coming together for you.

    Thanks,
    Zack

  • Anonymous

    love your blog and writing on doing gwt right.  you’re the doug crockford for gwt!    (i hope you take that as the compliment it’s intended to be.  :) )

    anyway, i wanted to suggest a tool for remote js debugging, check out the amazing wiener -> http://phonegap.github.com/weinre/ - the nitobi boys are pretty fantastic.

  • http://www.zackgrossbart.com Zack Grossbart

    Thank you very much. I’m always looking for good debugging options for mobile. I’ll check it out.

  • Dan S.

    Hey Mike If you have figured this out could you post to gitHub?  I’m trying to create an ipad site that changes the slider width according to the device orientation.  

  • Dan S.

    Hey Mike, 

    could you post your solution to gitHub?  I am trying to create an iPad specific site with a slider that  adjusts according to the device orientation.  

  • bipin tripathi

    thank you sir, can please help me how to integrate vertical scroll on each row

  • http://www.hyaho.ch riccardo

    Hello Zack, thanks for this input! I can use it in a current project very well! But I’d need it to snap in the middle of each cell, not at its left edge! And: the snap point should be in the middle of the container… so i can see what items are left of the snapped item and what items are right of it… how could I achieve this? I greatly appreciate any help!

  • http://www.zackgrossbart.com Zack Grossbart

    Take a look at the slideMomentum function.  That’s where we calculate the correct left for the slide.  Just add the width of the column / 2 to that left and it should slide to the middle of the cell instead of the left side.

  • http://www.hyaho.ch riccardo

    thanks for your reply!

    i’ve got one more question though :-/ hope you can help me!

    as i said i want to center the snap. i’ve done this now by css. also, i want to place the snapped item in the middle of the container. i’ve done this with css too, by just adding a margin-left to the whole slider. now there seems to be a problem when sliding to the last items. the slider works fine for some of the first elements, but when reaching the last cells it somehow doesnt snap right… i think the problem lies in touchEnd() when checking if dragged to the left past the last item… it somehow doesnt work for my situation (centered snapped item). can you give me a hint how to solve this?

    you can test this behaviour on ipad/iphone here: http://www.hyaho.ch/test

    thanks!
    r.

  • http://www.zackgrossbart.com Zack Grossbart

    I suspect your project is caused by adjusting the left position in the CSS. The slider uses CSS to move the panel and it will get confused if you set the left as well.

  • http://pulse.yahoo.com/_GFFXD7HGIY3LDA7NHOAZ4W2QLQ duc b

    Hi,

    Love your tutorial! Please continue doing what your doing to help amateur like me.
    Is there a way we can do one where it rotate both landscape and portrait? 

  • http://www.zackgrossbart.com Zack Grossbart

    Thank you for reading. It should be possible to make it rotate in both directions, but that would take some more coding.

  • http://twitter.com/ErikVeland Erik Veland

    Thank you for an invaluable script. We’ve implemented it on our ecommerce site at https://vulytrampolines.com/store (at the bottom). I’m having a couple of issues with it:

    My slider is a list of links in the form of a ul with a background image and LIs with links that overlay it. For some reason the links don’t always follow the slide when sliding quickly (like the lis and the ul get out of sync?). The other problem is that it is easy to tap a link when you meant to drag. It seems that if you register a tap on a link first and then continue to drag, at the end of the drag it will go to that link or worse the link that’s now in the original spot you tapped. Is there a way of avoiding this?

  • http://twitter.com/ErikVeland Erik Veland

    Thank you for an invaluable script. We’ve implemented it on our ecommerce site at https://vulytrampolines.com/store (at the bottom). I’m having a couple of issues with it:

    My slider is a list of links in the form of a ul with a background image and LIs with links that overlay it. For some reason the links don’t always follow the slide when sliding quickly (like the lis and the ul get out of sync?). The other problem is that it is easy to tap a link when you meant to drag. It seems that if you register a tap on a link first and then continue to drag, at the end of the drag it will go to that link or worse the link that’s now in the original spot you tapped. Is there a way of avoiding this?

  • http://twitter.com/ErikVeland Erik Veland

    I’ve changed it around again to using divs and animating left instead of “margin-left”, and fixed scrolling for the desktop. The issues still remain on the iOS touch slider however. It looks like the out of sync text could be related to the links active class?

  • http://www.zackgrossbart.com Zack Grossbart

    The issue of taps activating links is a tough one. The correct fix for this is to add a small delay to see if the tap is a single tap or part of a larger slide gesture. The slider doesn’t do much of that right now, but the code is open source and you could make that change with a little tweaking or hire someone to do it.

    Good luck,
    Zack

  • Sander

    Hi Zack,

    great stuff! by far out of my reach to program it myself :)

    I got this script into my little test site of WP and the WP touch plugin (for the mobiles)
    One page i want to have this plugin. So i added it. but keep getting this message :

    TypeError: ‘undefined’ is not a function (evaluating ‘$(gridid)’)Line:32Am i missing something?testurl : http://yeonactivities.nl/sushi/wp/?page_id=6

  • http://www.zackgrossbart.com Zack Grossbart

    I’m not sure what is causing that problem.  I would double-check your HTML and make sure that it looks like the sample HTML in this simple sample:  http://www.zackgrossbart.com/extras/touchslider

  • noponies

    Thanks for this script. Very useful.

    I’ve adjusted it to include a ‘clickToScroll’ method that allows for left/right manual scrolling, added in support for Firefox, ie10, opera, a call back method that optionally fires at the end of each scroll movement, a jquery non CSS3 browser fallback animation and allowed for different width elements while retaining the snapping.

    Thanks again.

  • Greg

    It seems to be very laggy when using viewport initial-scale=1.0

  • http://www.zackgrossbart.com Zack Grossbart

    I’m not sure what you mean about the viewport initial-scale. Could you please give me a little more context. Thanks.

  • Justintime Sohi

    it’s nice..could u plz explain how to implement a vertical slider in jquery mobile? i am developing mobile app using phonegap and jquery mobile..i know about the horizontal slider provided by jqm..it would b great if you solve this problem as lot of newbies are looking for this slider..im looking for a vertical slider similar to http://jqueryui.it/demos/slider#slider-vertical in jquery MOBILE…

  • http://www.zackgrossbart.com Zack Grossbart

    Thank you for checking out the slider. This slider only works horizontally. It wouldn’t be too hard to make it work vertically, but it would take some coding. If you aren’t familiar with JQuery and JavaScript you could hire someone to make the change.

    Thanks,
    Zack

  • Crungmungus

    Very slow on android 3 :-(

  • http://www.zackgrossbart.com Zack Grossbart

    I haven’t had a chance to try it on Android 3. What device and browser are you using?

  • kev

    I have a couple of links in the first cell that leads to other divs inside the slidebar. The problem is that after clicking a link ex. (#div3), I can no longer scroll left. How can I fix this?

  • http://www.zackgrossbart.com Zack Grossbart

    It should be possible to make this work. How are you handling the link to the other cells? Are you consuming the event from the anchor click?

  • Leinekuh

    Hi Zack,

    nice slider. Works Good. I found only one bug I can’t seem to solve myself easily. I am using the slider on two menu elements. The problem is that the slider seems to ‘forget’ the max right of the first loaded/enabled slider. 

    So let’s say slider A is 400px wide and slider B is 1200px wide, both in a div width of 100px. The problem is slider A can slide out of view once slider B is loaded because max right is now 1200px instead of the 400px it should be. 

    Any ideas on how to fix this?

  • http://www.zackgrossbart.com Zack Grossbart

    It should work to have multiple sliders in the same page, but I haven’t spent much time testing that scenario. The two instances of the slider are probably sharing some variable and getting confused with the position of the slider.

    The best fix for this is probably to convert the slider into a JQuery plugin which isolates the variables for each instance. That might be a bigger change than you’re up for, but if you give it a try please share the code.

    Thanks,
    Zack

  • Derek Rush

    just a tip… the code in touchMove sould use your touchslider.doSlide function to avoid a jumpy scroll

    elem.css(“left”, “-” + (jsslide.startX – e.targetTouches[0].clientX -
    jsslide.startLeft) + “px”);
    should be
    touchSlider.doslide(elem, “-” + (jsslide.startX – e.targetTouches[0].clientX – jsslide.startLeft), 0);

  • Damir

    Hi,
    Thanks for the great script :)

    Is there a way to specify cell width in percents (like 100%) ?
    Problem is when you flip phone sideways than you see half of second cell. Is there a way to fix this?

    Another question is seems like the swipe is very sensitive, if swiped harder it snaps to 2-4 cells to the right. Is there away to make this snap to next cell no matter how hard you swipe?

    Thank you soo much for your time.

  • http://www.zackgrossbart.com Zack Grossbart

    Making it use percentages is tricky since we don’t know the size of the screen and can’t position the cell. A better solution would be to detect the orientation of the phone and adjust the slider when it turns.

    The sliding multiple cells is part of the velocity of the control, but it would be pretty easy to take that out and just make it slide on cell each time.

    Both of these could be done with a little bit of coding change.

  • Marcus

    The framerate is kinda brutal, no? I am working on a jQuery slider plugin that uses hardware acceleration to boost the framerate. Check it out and tell me what you think! :D
    http://iosscripts.com/iosslider-jquery-horizontal-slider-for-iphone-ipad-safari/

  • http://www.zackgrossbart.com Zack Grossbart

    Awesome. This slider is using CSS3 transforms to do the slide which should hopefully take advantage of hardware acceleration. How are you doing it?

  • Marcus

    Hi Zack, thanks for the reply! I am using the CSS3 transforms in conjunction with some physics within the JavaScript calculations to smooth things over. It’s still a work in progress though…

  • Bisa

    Hi Zack,
    Thanksa lot for your job, is really well done and was exactly what I was looking for.
    I’m not capable to write code so I was looking for somenthing like that to improve woodwing capabilities that is the sw I’m using as a graphic.

    I’m wondering if it’s possible to add a function to your work to make the slide circukar as cicle. I mean that once you reach the end if you keep going sliding the next cell will be the first of the show.

    I’m also wondering how to transform it in a vertical slide. It’s possible doing it just changins some parameter and Css? Can you help me?

  • http://www.travellerbase.net John

    Thank You , Nice Work But css3 still difficult to adopt

  • http://www.zackgrossbart.com Zack Grossbart

    Both of those features should be possible, but they would take a little code. You can’t do it with just CSS. If you give it a try please share your results if you give it a try.

  • Pingback: Mobile by hfernety - Pearltrees

  • Hubert Jarema

    Zack, What do I need to use jQuery “touch” events? Are they included in standard jQuery library? Thank you!

  • http://www.zackgrossbart.com Zack Grossbart

    I’m not sure I understand your question. This script just binds to the browsers native touch events. There aren’t any special JQuery touch events.

  • Hubert Jarema

    So I don’t need any extra libraries to use those:
    ontouchstart

    ontouchmove

    ontouchend

    They are part of the mobile browser not jQuery?

  • http://www.zackgrossbart.com Zack Grossbart

    That’s correct.

  • Matt

    Hi Zack,
    Thanks for you comment here. I am trying to do something similar but not having any luck restoring the default vertical scroll so that my horizontal scroll areas don’t prevent normal page scrolling.  I’m trying to implement something like:
     if (Math.abs(touchslider.startY- e.targetTouches[0].clientY) > 20) {
                    return false;
              }

    Any tips you might have would be much appreciated.
    Thanks

  • http://www.zackgrossbart.com Zack Grossbart

    Hi Matt,

    It sounds like you’re on the right track, but you normally don’t return false to not consume the event. The two functions that controls event propagation are preventDefault and stopPropagation. Make sure you don’t call these two functions during a vertical touch move and it should allow the browser to scroll vertically.

    Please share if you get it working.

    Thanks,
    Zack

  • Hooters

    very choppy on iPad.. shame

  • Nomadman

    Hello Zack
    I love your work
    TY a lot
    Just a question
    i want to move the slidebar to a specific cell with the div id by clicking on a external link
    someting like 

    could you please tell me how to do it?
    Tks
    Nomadman

  • http://www.zackgrossbart.com Zack Grossbart

    Try something like this:

    touchslider.doSlide(‘#slideBar’, ‘-’ + touchslider.getLeft($(‘#rabbit’)), ’1s’);

  • Shaun Paul

    Hi Zack, hope you had a great Christmas.

    I’ve finally used the touch slider on a love website which you can see here: http://www.bellydancingbarbie.com/

    As you will see I have the touch slider with auto-scroll and with some buttons below to choose a slide if preferred. I’ve also got it so depending what slide is showing, it updates the little buttons with an .activeSlide class so it styles it to make it clear what slide your on. I’ve also added the functionality so when you hover very with a mouse, it pauses the auto-scroll and once mouseOut it carries on’ which is pretty sweet.

    The only issue I am having is with the actual updating of the .activeSlide class when using the touchSlide. Basically if I me the slider using touch, the class isn’t added to the selector buttons. I know in theory I have to get the current left position on endTouch and then assign that a value, so if left position was 0px on end touch, then i=0 or is they have slide to the last image say, then left would be -3192px and i=4. However I am completely clueless how to include this in the code. 

    So I’ll clarify, I have 5 images at 798px wide for a total of 3990px.

    #img0 should be i=0 (left: 0px)
    #img1 should be i=1 (left: -798px)
    #img2 should be i=2 (left: -1596px)
    #img3 should be i=3 (left: -2394px)
    #img4 should be i=4 (left: -3192px)

    Do you have any advice on how to achieve this? Also ignore how crappy my JavaScript is for the way I’m getting the active class on he buttons and stuff, I’m garbage at it and it’s way bloated but it works for now and can always be cleaned up at some stage as I learn more.

    Cheers and I appreciate any help or advice. If I don’t hear from yobs fore New Year, then have a great one and I’ll speak in 2012,
    Shaun Paul

  • http://www.zackgrossbart.com Zack Grossbart

    You could probably do this in a better way. Get the left position of the slider and then figure out the tag at that position. Then you could keep a map linking the DOM elements representing the DIV tags and the dot you want to highlight on the bottom.

  • Shaun Paul

    Hey Zack.

    I think I understand what you’re saying but unfortunately I’m completely unsure how I would go about doing that.

    Are you saying that I create a function that checks for the left element after each setTimeout of 7500, then check what the div is?

    ie is it #img0 or #img1 say, then depending what it is set i to whatever number represents that slide? So it what get the left element as say -1596px, would know that was #img1 and set i=1

    As I say, I think I understand what your saying I should do, I just don’t really know how to ;)

  • http://www.zackgrossbart.com Zack Grossbart

    Instead of a timer you might want to go with a listener model. Change the slider to call you back when it slides so you can tell which DIV is selected. You might want to hire someone to help you with the code if this is more than you’re comfortable with.

    Good luck,
    Zack

  • Pingback: I LEARN HTML5 by norkhat - Pearltrees

  • Mdcarroll6

    How would I do this in an HTML file?

  • http://www.zackgrossbart.com Zack Grossbart

    I don’t understand your question. This example is in an HTML file.

  • http://twitter.com/julianwachholz Julian Wachholz

    Your ‘coding style’ just hurt my feelings.
    You 1) don’t use jQuerys plugin capabilities and 2) do all this in a global object with 3) no chance for multiple instances on the same page and 4) provide no ability to configure it.

    Shame this pops up so high on Google. :( No offense, I bet you could’ve done better and made it a real jQuery plugin, but the problem is people find this and use it without thinking. And I eventually end up having to work with this.

  • http://www.zackgrossbart.com Zack Grossbart

    You’re right that making those changes would make this a better jQuery plugin, but it isn’t trying to be a jQuery plugin. This article is intended as an example and an introduction to touch events. I wanted to make the code as easy to follow as possible and that means keeping it simple.

    If you’re interested in creating a jQuery plugin out of this or making the other changes you’ve mentioned I’d be happy to link to it.

    Thanks,
    Zack

  • Fawzi_masri

    Great slider… thanks…
    i am trying to get the id of the div that is in the center of your ‘slidecont’ div, but i am wondering if there is more straight forward way to get it out your code.  currently i am doing location comparison to get that id.  i am thinking your code should probably spit out the id of the div where it stopped, but cannot figure out your code .. i cannot even get a console.log out of it neither…
    any guidance would be much appreciated…

  • http://www.zackgrossbart.com Zack Grossbart

    The script just uses the DIVs that were already there. If you want the one in the middle just give it an ID. The script won’t change it.

  • Fawzi_masri

     yes, but what i am trying to find out basically is what id is the user currently looking at… in another words, at what id did the ‘sliding’ stop.  this way i can do other stuff in the page based on what image is showing.
    using $(‘slidecont div.cell:visible’)  gives me all the cells, since they are all visible.  so i currently check each of them to see which is within my container div and then use its id.
    is there a way to send a trigger out from your slider at the stop of sliding with the id of the div in view?
     

  • http://www.zackgrossbart.com Zack Grossbart

    There isn’t a good way to get the left most visible cell. You can get the left property and find the div based on the width of the cells and knowing each div is the same width.

  • Fawzi_masri

     ok, thanks….one last question though, is there a way to trigger a ‘Slide_completed’ event from your code…. i tried to place an event in touchEnd, but i am not sure if this is the place to put it, and  where exactly to do so.

  • http://www.zackgrossbart.com Zack Grossbart

    Adding an event in touch end seems as good as anywhere.

  • Arnau

    Hi, 
    First of all good work! It’s really useful for me. But I would like to change the behaviour in the left and right limits so there’s no slide at all. it’s that possible? I can not find any solution…

  • http://www.zackgrossbart.com Zack Grossbart

    It possible to do that, but you would need to write a little code. Right now we keep moving as long as you keep dragging. You would have to add a limit in either direction and stop the movement.

  • Michelle

    ooo it is not working on blackberry.. Did i maybe do something wrong? 

  • http://www.zackgrossbart.com Zack Grossbart

    I don’t have a Blackberry to try this with. Anyone else had a chance to try it on Blackberry?

  • Laptop

    Can I download this version somewhere?

  • Urbanrunic

    I’m having a problem with Blackberry as well. Can’t scroll at all. There is no scrollbar and cause I can not touch it’s static.

  • Sumanthdatta

    hai,

    i have tried it on playbook, scroll is working fine. but in my application , if i click on the image it should open a new page,iam unable to figure out the click event for this , i want  this  to move with my finger  movement  and support the tap or click event . plz  help me out with this 

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for using the script. I’m not really sure what you’re trying to do. Can you give me some more details about what you’re trying and what issue you’re seeing.

    Thanks,
    Zack

  • Rajeevr Raina

    Has anybody tried it on Blackberry and Symbian? It is not working for me. Please help.

  • http://profiles.google.com/rentgeeen Radek Valachovic

    Hello sorry for stupid question,

    What does those 2 number means?

    $(document).ready(function() {    touchslider.createSlidePanel(‘#slidebar’, 200, 15);});

     200, 15

    I know sildebar which to slide + the numbers like speed or what?

    Thanks

  • http://www.zackgrossbart.com Zack Grossbart

    The first number is the width of each cell and the second number is the padding you want between the cells. Both numbers are in pixels.

  • http://aalaap.com Aalaap Ghag

    This is one of the rare few touch slider plugins that work with the Windows Phone 7 IE Mobile, but it doesn’t snap to the beginning of a div. It just pans it left or right like a regular scroller. Let’s see if I can figure out what’s wrong…

  • http://www.zackgrossbart.com Zack Grossbart

    Thanks for taking a look. I don’t have a Windows phone to test it on.

  • http://twitter.com/x4er0 x4er0

    Sorry on Dell Vostro doesn’t work touch…

  • http://twitter.com/_hegarty Terence Hegarty

    Zach – phenomenal script – nice work – quick question how can I keep the scrollbar present 100% of the time. Amazing I can’t find it in the browser’s inspector nor in your JS or CSS

  • http://www.zackgrossbart.com Zack Grossbart

    Do you mean that you want the scroll bar in the mobile case? That would just be a scrolling panel and wouldn’t do the touch slide.

  • http://twitter.com/_hegarty Terence Hegarty

    I had a css issue, which is now resolved. However I have one other question: I have 2 scrolling areas on a single page. The first one scrolling area seems to be picking up the configuration of the second one. How can I use the same code for 2 scrolling areas on the same page?

  • http://twitter.com/_hegarty Terence Hegarty

    Thanks by the way – the script is awesome- i will send you a link once we go live with the redesign of Ora.tv

  • http://www.mukispace.com muki

    I can’t work if i changeed ID to Class, or use two above slider in one web page :(

  • the_farmer

    Hi Zack,
    I am using this nice solution.
    instead of images and text I am using buttons inside the slider and it works great with all platforms.
    I just notice that when I have updated my Iphone to 6.1.2 +  the buttons are not clickable.
    any idea way?

  • http://www.zackgrossbart.com Zack Grossbart

    It sounds like they may have changed something in the way they handle the button tap events. It sounds like you need to do a little debugging.

    Good luck,
    Zack

  • Pingback: Creating a Mobile Touch Slide Panel with JQuery | Création Numérique

  • J Criscola

    Hi Zack, any way to make each cell be a auto width instead of fixed? Now it iis only 200, correct?
    Thanks

  • http://www.zackgrossbart.com Zack Grossbart

    The script right now depends on the cells being a fixed width. You could change it to some other number, but not to an automatic width. However, there’s not reason it wouldn’t work with an automatic width. It would just take a little more code.

    Good luck,
    Zack

  • Matt

    I want to add this as an enhancement to a carousel that I currently have live. Do you have any reccomendations on how to do this? Is all the code still necessary, like the gridid?

  • http://www.joelannen.com/ Joe Lannen

    What about allowing you to scroll vertically if your touch originates inside the slider and you’re trying to scroll down?