JAVASCRIPT   76

MultiSlider

Guest on 7th May 2022 02:27:02 AM

  1. /*
  2. *   MultiSlider | MIT License
  3. *
  4. *   Copyright (c)  Trevor Blackman
  5. *   http://www.multislider.info
  6. *
  7. */
  8.  
  9. (function($){
  10.  
  11.     // ==== BEGINS PLUGGIN ====
  12.     $.fn.multislider = function(data, callback){
  13.  
  14.         // ==== CACHE DOM ====
  15.         var $multislider = $(this);
  16.         var $msContent = $multislider.find('.MS-content');
  17.         var $msRight = $multislider.find('button.MS-right');
  18.         var $msLeft = $multislider.find('button.MS-left');
  19.         var $imgFirst = $msContent.find('.item:first');
  20.  
  21.         // === DETERMINE ACTION ====
  22.         // string = method | object or nothing is to initialize
  23.         if(typeof data === 'string'){
  24.             getStringArgs(data);
  25.             return $multislider;
  26.         } else if (typeof data === 'object' || typeof data  ==='undefined'){
  27.             init();
  28.         }
  29.  
  30.         // ==== PLUGGIN VARIABLES ====
  31.         var $imgLast,
  32.         totalWidth,
  33.         numberVisibleSlides,
  34.         animateDistance,
  35.         animateSlideRight,
  36.         animateSlideLeft,
  37.         defaults,
  38.         settings,
  39.         animateDuration,
  40.         autoSlideInterval;
  41.  
  42.         // = INITIALIZE =
  43.         function init(){
  44.             minifyContent();        // minify html
  45.             createSettings();       // merge defaults and user provided options
  46.             saveData();             // add data object to DOM el with reference to animation functions, allows for methods to reference at any time
  47.             selectAnimations();     // choose default animation
  48.         }
  49.  
  50.  
  51.         // ==== EVENT HANDLERS ====
  52.         $msRight.on('click', animateSlideLeft);
  53.         $msLeft.on('click', animateSlideRight);
  54.         $multislider.on('click','.MS-right, .MS-left', resetInterval);
  55.         $(window).on('resize', findItemWidth);
  56.  
  57.  
  58.         // ==== FUNCTIONS (for days...) ====
  59.         // =================================
  60.  
  61.         function pauseAbove(){
  62.             if (window.innerWidth > settings.pauseAbove){ $multislider.addClass('ms-PAUSE'); }
  63.             $(window).on('resize',function(){
  64.                 if (window.innerWidth > settings.pauseAbove){
  65.                     $multislider.addClass('ms-PAUSE');
  66.                 } else {
  67.                     $multislider.removeClass('ms-PAUSE');
  68.                 }
  69.             });
  70.         }
  71.  
  72.         function pauseBelow(){
  73.             if (window.innerWidth < settings.pauseBelow){ $multislider.addClass('ms-PAUSE'); }
  74.             $(window).on('resize',function(){
  75.                 if (window.innerWidth < settings.pauseBelow){
  76.                     $multislider.addClass('ms-PAUSE');
  77.                 } else {
  78.                     $multislider.removeClass('ms-PAUSE');
  79.                 }
  80.             });
  81.         }
  82.  
  83.         // used if method is called after initialization
  84.         function getStringArgs(str){
  85.             if (typeof $multislider.data(str) !== 'undefined'){
  86.                 $multislider.data(str)();
  87.             } else {
  88.                 console.error("Multislider currently only accepts the following methods: next, prev, pause, play");
  89.             }
  90.         }
  91.  
  92.         // saves data object to DOM element
  93.         function saveData(){
  94.             $multislider.data({
  95.                 "pause":function(){ $multislider.addClass('ms-PAUSE'); },
  96.                 "unPause":function(){ $multislider.removeClass('ms-PAUSE'); },
  97.                 "continuous":function(){ $multislider.removeClass('ms-PAUSE'); continuousLeft(); },
  98.                 "next":function(){ overRidePause(singleLeft); },
  99.                 "nextAll":function(){ overRidePause(allLeft); },
  100.                 "prev":function(){ overRidePause(singleRight); },
  101.                 "prevAll":function(){ overRidePause(allRight); },
  102.                 "settings":settings
  103.             });
  104.         }
  105.  
  106.         // used when calling 'next', 'prev' methods
  107.         function overRidePause(animation){
  108.             if ($multislider.hasClass('ms-PAUSE')){
  109.                 $multislider.removeClass('ms-PAUSE');
  110.                 animation();
  111.                 $multislider.addClass('ms-PAUSE');
  112.             } else {
  113.                 animation();
  114.             }
  115.             resetInterval();
  116.         }
  117.  
  118.         // CRITICAL for items to be perfectly side-by-side without floating them
  119.         function minifyContent(){
  120.             $msContent.contents().filter(function(){
  121.                 return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
  122.             }).remove();
  123.         }
  124.  
  125.         // updated options with defaults, measure slide widths for animation calculations, carry out setting implementations
  126.         function createSettings() {
  127.             defaults = settings || {
  128.                         continuous: false,      // endless scrolling with no pauses
  129.                         slideAll: false,        // slide all visible slides, or just one at a time
  130.                         // autoSlide: true,     // DEPRECATED
  131.                         interval: 2000,         // time bewteen slide animation, 0 or 'false' prevents auto-sliding
  132.                         duration: 500,      // duration of slide animation
  133.                         hoverPause: true,       // pause slideshow on hover
  134.                 pauseAbove: null,   // pause above specified screen width
  135.                 pauseBelow: null    // pause below specified screen width
  136.                 };
  137.  
  138.                 settings = $.extend({},defaults,data);
  139.  
  140.             findItemWidth();
  141.             animateDuration = settings.duration;
  142.  
  143.             if (settings.hoverPause){pauseHover();}
  144.             // autoSlide is being depricated | Feb 2 2017
  145.             if (settings.continuous !== true && settings.interval !== 0 && settings.interval !== false && settings.autoSlide !== false){autoSlide();}
  146.             if (settings.pauseAbove !== null && typeof settings.pauseAbove === 'number'){ pauseAbove(); }
  147.             if (settings.pauseBelow !== null && typeof settings.pauseBelow === 'number'){ pauseBelow(); }
  148.         }
  149.  
  150.         // determine between single and multi-slide animations
  151.         function selectAnimations () {
  152.             if (settings.continuous){
  153.                 settings.autoSlide = false;
  154.                 continuousLeft();
  155.             } else if (settings.slideAll){
  156.                 animateSlideRight = $multislider.data('prevAll');
  157.                 animateSlideLeft = $multislider.data('nextAll');
  158.             } else {
  159.                 animateSlideRight = $multislider.data('prev');
  160.                 animateSlideLeft = $multislider.data('next');
  161.             }
  162.         }
  163.  
  164.         // measure slide width, for animation calculations
  165.         function findItemWidth(){
  166.             reTargetSlides();
  167.             animateDistance = $imgFirst.width();
  168.             var left = parseInt($msContent.find('.item:first').css('padding-left'));
  169.             var right = parseInt($msContent.find('.item:first').css('padding-right'));
  170.             if (left !== 0){animateDistance += left;}
  171.             if (right !== 0){animateDistance += right;}
  172.         }
  173.  
  174.         // recursive auto-slide loop
  175.         function autoSlide() {
  176.             autoSlideInterval = setInterval(function(){
  177.                 if (!$multislider.hasClass('ms-PAUSE')){
  178.                     animateSlideLeft();
  179.                 }
  180.             }, settings.interval);
  181.         }
  182.  
  183.         function resetInterval() {
  184.             if (settings.interval !== 0 && settings.interval !== false && settings.continuous !== true){
  185.                 clearInterval(autoSlideInterval);
  186.                 autoSlide();
  187.             }
  188.         }
  189.  
  190.         // target first and last visible slides before each new animation
  191.         function reTargetSlides(){
  192.             $imgFirst = $msContent.find('.item:first');
  193.             $imgLast = $msContent.find('.item:last');
  194.         }
  195.  
  196.         // prevent animation firing if multislider is currently animating
  197.         // all animations pass through this function, which emits events, and adds/removes animating class
  198.         function isItAnimating(callback){
  199.                         if(!$multislider.hasClass('ms-animating') &&
  200.                !$multislider.hasClass('ms-HOVER') &&
  201.                !$multislider.hasClass('ms-PAUSE')){
  202.                     $multislider.trigger('ms.before.animate'); // event!
  203.                     $multislider.addClass('ms-animating');
  204.                     callback();    //callback is animation
  205.                         }
  206.                 }
  207.  
  208.         // update multislider at the end of each animation
  209.         function doneAnimating() {
  210.                         if($multislider.hasClass('ms-animating')){
  211.                                 $multislider.removeClass('ms-animating');
  212.                 $multislider.trigger('ms.after.animate'); // event!
  213.             }
  214.                 }
  215.  
  216.         // logic for pausing and restarting the multislider on hover
  217.         function pauseHover() {
  218.             // continuous scroll pause slightly different
  219.             if(settings.continuous){
  220.                                 $msContent.on('mouseover',function(){
  221.                                         doneAnimating();
  222.                                         $msContent.children('.item:first').stop();
  223.                                 });
  224.                                 $msContent.on('mouseout',function(){
  225.                                         continuousLeft();
  226.                                 });
  227.                         } else {
  228.             // regular animation pausing
  229.                 $msContent.on('mouseover',function(){
  230.                     $multislider.addClass('ms-HOVER');
  231.                 });
  232.                 $msContent.on('mouseout',function(){
  233.                     $multislider.removeClass('ms-HOVER');
  234.                 });
  235.                         }
  236.         }
  237.  
  238.         // calculate remaining animation, if stopped mid-animation and resuming
  239.         function midAnimateResume(){
  240.             animateDuration = settings.duration;
  241.             var currentMargin = parseFloat($msContent.find('.item:first').css("margin-left"));
  242.             var percentageRemaining = 1-(currentMargin/-(animateDistance-1));
  243.             animateDuration = percentageRemaining*animateDuration;
  244.         }
  245.  
  246.         // determine how many slides need to be moved over, if slideAll is true
  247.         function calcNumSlidesToMove(){
  248.             totalWidth = $msContent.width();                                                      // total width of .MS-content containing all visible slides
  249.                     numberVisibleSlides = Math.floor(totalWidth/animateDistance);     // number of (visible) slides needed to be moved in each animation
  250.         }
  251.  
  252.  
  253.         // ==== ANIMATION FUNCTIONS ====
  254.         // =============================
  255.         function continuousLeft () {
  256.             isItAnimating(function(){
  257.                 reTargetSlides();
  258.                 midAnimateResume();
  259.                 $imgFirst.animate(
  260.                     {marginLeft: -(animateDistance+1)},
  261.                     {
  262.                         duration: animateDuration,
  263.                         easing: "linear",
  264.                         complete: function(){
  265.                             $imgFirst.insertAfter($imgLast).removeAttr("style");
  266.                             doneAnimating();
  267.                             continuousLeft ();
  268.                         }
  269.                     }
  270.                 );
  271.             });
  272.         }
  273.  
  274.         function allLeft(){
  275.             isItAnimating(function(){
  276.                 reTargetSlides();
  277.                 calcNumSlidesToMove();
  278.  
  279.                 var $clonedItemSet = $msContent.children('.item').clone();
  280.                 var filteredClones = $clonedItemSet.splice(0, numberVisibleSlides);
  281.  
  282.                 $msContent.append(filteredClones);
  283.  
  284.                 $imgFirst.animate(
  285.                     {marginLeft: -totalWidth}, {
  286.                         duration: animateDuration,
  287.                         easing: "swing",
  288.                         complete: function(){
  289.                             $($msContent.children('.item').splice(0,numberVisibleSlides)).remove();
  290.                             doneAnimating();
  291.                         }
  292.                     }
  293.                 );
  294.             });
  295.         }
  296.  
  297.         function allRight() {
  298.             isItAnimating(function(){
  299.                 reTargetSlides();
  300.                 calcNumSlidesToMove();
  301.  
  302.                 var numberTotalSlides = $msContent.children('.item').length;
  303.                 var $clonedItemSet = $msContent.children('.item').clone();
  304.                 var filteredClones = $clonedItemSet.splice(numberTotalSlides-numberVisibleSlides,numberTotalSlides);
  305.  
  306.                 $($(filteredClones)[0]).css('margin-left',-totalWidth); // give clone array negative margin before preppending
  307.                 $msContent.prepend(filteredClones);
  308.  
  309.                 reTargetSlides();
  310.  
  311.                 $imgFirst.animate(
  312.                     {
  313.                         marginLeft: 0
  314.                     }, {
  315.                         duration: animateDuration,
  316.                         easing: "swing",
  317.                         complete: function(){
  318.                             numberTotalSlides = $msContent.find('.item').length;
  319.                             $($msContent.find('.item').splice(numberTotalSlides-numberVisibleSlides,numberTotalSlides)).remove();
  320.                             $imgFirst.removeAttr('style');
  321.                             doneAnimating();
  322.                         }
  323.                     }
  324.                 );
  325.             });
  326.         }
  327.  
  328.         function singleLeft(){
  329.             isItAnimating(function(){
  330.                 reTargetSlides();
  331.                 $imgFirst.animate(
  332.                     {
  333.                         marginLeft: -animateDistance
  334.                     }, {
  335.                         duration: animateDuration,
  336.                         easing: "swing",
  337.                         complete: function(){
  338.                             $imgFirst.detach().removeAttr('style').appendTo($msContent);
  339.                             doneAnimating();
  340.                         }
  341.                     }
  342.                 );
  343.             });
  344.         }
  345.  
  346.         function singleRight(){
  347.             isItAnimating(function(){
  348.                 reTargetSlides();
  349.                 $imgLast.css('margin-left',-animateDistance).prependTo($msContent);
  350.                 $imgLast.animate(
  351.                     {
  352.                         marginLeft: 0
  353.                     }, {
  354.                         duration: animateDuration,
  355.                         easing: "swing",
  356.                         complete: function(){
  357.                             $imgLast.removeAttr("style");
  358.                             doneAnimating();
  359.                         }
  360.                     }
  361.                 );
  362.             });
  363.         }
  364.         return $multislider;
  365.     }
  366. })(jQuery);

Raw Paste


Login or Register to edit or fork this paste. It's free.