#StackBounty: #javascript #jquery #css #image #html5 jQuery image carousel

Bounty: 50

I have made this custom image carousel, using HTML5, jQuery and CSS. My aim was to make it really lightweight but with (just) enough features: “bullets”, auto-advance, responsiveness.

<

div class=”snippet”>

<

div class=”snippet-code”>

var $elm = $('.slider'),
  $slidesContainer = $elm.find('.slides-container'),
  slides = $slidesContainer.children('a'),
  slidesCount = slides.length,
  slideHeight = $(slides[0]).find('img').outerHeight(false),
  animationspeed = 1500,
  animationInterval = 7000;

var shuffle = function(slides) {
  var j, x, i;
  for (i = slides.length - 1; i > 0; i--) {
    j = Math.floor(Math.random() * (i + 1));
    x = slides[i];
    slides[i] = slides[j];
    slides[j] = x;
  }
  return slides;
}

shuffle(slides);

// Set (initial) z-index for each slide
var setZindex = function() {
  for (var i = 0; i < slidesCount; i++) {
    $(slides[i]).css('z-index', slidesCount - i);
  }
};
setZindex();

var setActiveSlide = function() {
  $(slides).removeClass('active');
  $(slides[activeIdx]).addClass('active');
};

var advanceFunc = function() {
  if ($('.slider-nav li.activeSlide').index() + 1 != $('.slider-nav li').length) {
    $('.slider-nav li.activeSlide').next().find('a').trigger('click');
  } else {
    $('.slider-nav li:first').find('a').trigger('click');
  }
}

var autoAdvance = setInterval(advanceFunc, animationInterval);

//Set slide height
$(slides).css('height', slideHeight);

// Append bullets
if (slidesCount > 1) {
  /* Prepend the slider navigation to the slider
     if there are at least 2 slides */
  $elm.prepend('<ul class="slider-nav"></ul>');

  // make a bullet for each slide
  for (var i = 0; i < slidesCount; i++) {
    var bullets = '<li><a href="#">' + i + '</a></li>';
    if (i == 0) {
      // active bullet
      var bullets = '<li class="activeSlide"><a href="#">' + i + '</a></li>';
      // active slide
      $(slides[0]).addClass('active');
    }
    $('.slider-nav').append(bullets);
  }
};

var Queue = function() {
  var lastPromise = null;

  this.add = function(callable) {
    var methodDeferred = $.Deferred();
    var queueDeferred = this.setup();
    // execute next queue method
    queueDeferred.done(function() {

      // call actual method and wrap output in deferred
      callable().then(methodDeferred.resolve)
    });
    lastPromise = methodDeferred.promise();
  };

  this.setup = function() {
    var queueDeferred = $.Deferred();
    // when the previous method returns, resolve this one
    $.when(lastPromise).always(function() {
      queueDeferred.resolve();
    });
    return queueDeferred.promise();
  }
};

var queue = new Queue();
var slideUpDown = function(previousIdx, activeIdx) {
  queue.add(function() {
    return new Promise(function(resolve, reject) {
      // set top property for all the slides
      $(slides).not(slides[previousIdx]).css('top', slideHeight);
      // then animate to the next slide
      $(slides[activeIdx]).animate({
        'top': 0
      }, animationspeed);

      $(slides[previousIdx]).animate({
        'top': "-100%"
      }, animationspeed, 'swing', resolve);
    })
  })
};

var previousIdx = '0' // First slide
$('.slider-nav a').on('click', function(event) {
  event.preventDefault();
  activeIdx = $(this).text();

  // Disable clicling on an active item
  if ($(slides[activeIdx]).hasClass("active")) {
    return false;
  }
  $('.slider-nav a').closest('li').removeClass('activeSlide');
  $(this).closest('li').addClass('activeSlide');

  // Reset autoadvance if user clicks bullet
  if (event.originalEvent !== undefined) {
    clearInterval(autoAdvance);
    autoAdvance = setInterval(advanceFunc, animationInterval);
  }

  setActiveSlide();
  slideUpDown(previousIdx, activeIdx);
  previousIdx = activeIdx
});
body * {
  box-sizing: border-box;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
}

.slider {
  width: 100%;
  height: 300px;
  position: relative;
  overflow: hidden;
}

.slider .slider-nav {
  text-align: center;
  position: absolute;
  padding: 0;
  margin: 0;
  left: 10px;
  right: 10px;
  bottom: 2px;
  z-index: 10;
}

.slider .slider-nav li {
  display: inline-block;
  width: 20px;
  height: 4px;
  margin: 0 1px;
  text-indent: -9999px;
  overflow: hidden;
  background-color: rgba(255, 255, 255, .5);
}

.slider .slider-nav a {
  display: block;
  height: 4px;
  line-height: 4px;
}

.slider .slider-nav li.activeSlide {
  background: #fff;
}

.slider .slider-nav li.activeSlide a {
  display: none;
}

.slider .slider-container {
  width: 100%;
  text-align: center;
}

.slider .slides-container a {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.slider .slides-container img {
  transform: translateX(-50%);
  margin-left: 50%;
}
https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js

</div> </div>