jQuery Dynaslide - Multiple item content slider

Thursday, May 30, 2013

Before I start all credit for this plugin goes to 2pha.

Sitting around UI/UX designers I constantly hear their complaints & often technical criticisms of jQuery sliders. The recurring complaint that sliders often make too many assumptions of the developers end goal and thus provide markup which is inefficient & at times totally wrong for the desired output. This of course only relates to a small number of projects as the vast majority fit neatly into the norms.

Below could be considered standard (generic) markup for a slider.

  1. [start wrapper]
  2.   [start slider]
  3.     [start slider row]
  4.       [slider item]
  5.     [end slider row]
  6.     [start slider row]
  7.       [slider item]
  8.     [end slider row]
  9.   [end slider>]
  10.   [controls]
  11. [end wrapper]

While this is very nice it does limit our ability to customize the output; especially if we need less. What if we just want an unordered list with a single div used for wrapping our slide items?

The example below provides an easy to theme, implemented & use slider.


(function( $ ) {
  
  var methods = {
    init : function( options ) { 
      var settings = $.extend( {
        'nextButton' : true,
        'nextText' : 'next',
        'previousButton' : true,
        'previousText' : 'previous',
        'controls' : true,
        'resetFunction' : false,
        'addFloat' : true,
        'speed' : 500,
        'easingFunction' : 'swing',
      }, options);
      
      return this.each(function() {
        $(this).addClass('dynamslide-processed');
       
        var list = $(this).find('ul');
        var listitems = list.children('li'); 

        if (settings.addFloat){
          listitems.css('float', 'left');
        }
        
        // Add up what the total width should be by adding width of all li.
        var initialWidth = 0;
        listitems.each(function(){
          initialWidth += $(this).outerWidth(true);
        });
        list.css({'margin':'0px', 'padding':'0px', 'position':'absolute', 'left':'0px'}).width(initialWidth);
        
        // Add controls.
        if (settings.controls){
          var controls = $('<div class="dynamslide-controls"> </div>');
          $(this).after(controls);
          if (settings.previousButton){
            $('div.dynamslide-controls').append('
<div class="previous-button">'+settings.previousText+'</div>');
            $('.dynamslide-controls .previous-button').data('dynamslide', list).bind('click.dynamslide', {'settings' : settings}, methods.prev);
          }
          if (settings.nextButton){
            $('div.dynamslide-controls').append('
<div class="next-button">'+settings.nextText+'</div>');
            $('.dynamslide-controls .next-button').data('dynamslide', list).bind('click.dynamslide', {'settings' : settings}, methods.next);
          }
        }
        
        // Set first to current.
        listitems.first().addClass('current');
        
        // Add container div.
        list.wrap('
<div class="dynamslide-container" style="position:relative;overflow:hidden;width:100%;height:100%;"> </div>');
        
        // Bind reset function.
        if(settings.resetFunction){
          $('body').bind(settings.resetFunction, methods.reset);
        }
      });
    },
    next : function(event) {
      var list = $(event.target).data().dynamslide;
      //var listitems = list.children('li');
      var current = list.children('li.current');
      var ind = current.index();
      var remaining = list.find('li:gt('+ind+')');
      var remainingWidth = 0;
      remaining.each(function(){
        remainingWidth += $(this).outerWidth(true);
      });
      if (remainingWidth > list.parent().width()) {
        current.next('li').addClass('current').prev('li.current').removeClass('current');
      }
      methods.slideToCurrent(list, event.data.settings);
    },
    prev : function(event) { 
      var list = $(event.target).data().dynamslide;
      var current = list.children('li.current');
      current.prev('li').addClass('current').next('li.current').removeClass('current');
      methods.slideToCurrent(list, event.data.settings);
    },
    slideToCurrent : function(list, settings) {
      var pos = list.children('li.current').position();
      list.animate({'left':0-pos.left}, settings.speed, settings.easingFunction);
    },
    slideTo : function(index) {
      // @TODO.
    },
    reset : function() {
      // @TODO.
    }
  };

  $.fn.dynamslide = function( method ) {
    // Method calling logic.
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.dynamslide' );
    }
  };

})( jQuery );

Comments

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Target Image