×

Welcome to TagMyCode

Please login or create account to add a snippet.
0
0
 
0
Language: Javascript
Posted by: Isaac Dettman
Added: Nov 26, 2016 6:21 PM
Views: 3
Tags: carousel
  1. var Tray = function(props) {
  2.   var createElement = function(props) {
  3.     var element = document.createElement(props.elementType);
  4.     element.className = props.className;
  5.     return element;
  6.   };
  7.  
  8.   var trayCont = createElement({
  9.     elementType: 'div',
  10.     className: props.trayContClass || 'trayCont'
  11.   });
  12.  
  13.   var viewCont = createElement({
  14.     elementType: 'div',
  15.     className: props.viewContClass || 'viewCont'
  16.   });
  17.   trayCont.appendChild(viewCont);
  18.  
  19.   var items = props.items.map(props.itemTemplate);
  20.   var itemsPerPage = props.itemsPerPage;
  21.   var viewWidth;
  22.   var maxLeft;
  23.   var dotAmount;
  24.   var selectedDotClass = 'selectedDot';
  25.   var selectedDotClassReg = new RegExp('(?:^|[ ])' + selectedDotClass + '(?![^ ])', 'g');
  26.  
  27.   var slider = createElement({
  28.     elementType: 'div',
  29.     className: props.sliderClass || 'slider'
  30.   });
  31.   viewCont.appendChild(slider);
  32.  
  33.   items.forEach(function(item) {
  34.     slider.appendChild(item);
  35.   });
  36.  
  37.   var btnCont = createElement({
  38.     elementType: 'div',
  39.     className: props.btnContClass || 'btnCont'
  40.   });
  41.   viewCont.appendChild(btnCont);
  42.  
  43.   var prevBtn = createElement({
  44.     elementType: 'div',
  45.     className: props.prevBtnClass || 'prevBtn'
  46.   });
  47.   prevBtn.textContent = '<';
  48.   prevBtn.onclick = function() {
  49.     var left = parseInt(slider.style.left);
  50.     var newLeft = left >= 0 ? maxLeft : left + viewWidth;
  51.     newLeft = boundLeftIncrement(left, newLeft);
  52.     newLeft = checkDot(newLeft);
  53.     animateLeft(newLeft);
  54.   };
  55.   btnCont.appendChild(prevBtn);
  56.  
  57.   var nextBtn = createElement({
  58.     elementType: 'div',
  59.     className: props.nextBtnClass || 'nextBtn'
  60.   });
  61.   nextBtn.textContent = '>';
  62.   nextBtn.onclick = function() {
  63.     var left = parseInt(slider.style.left);
  64.     var newLeft = left <= maxLeft ? '0' : left - viewWidth;
  65.     newLeft = boundRightIncrement(left, newLeft);
  66.     newLeft = checkDot(newLeft);
  67.     animateLeft(newLeft);
  68.   };
  69.   btnCont.appendChild(nextBtn);
  70.  
  71.   var dotCont = createElement({
  72.     elementType: 'ul',
  73.     className: props.dotContClass || 'dotCont'
  74.   });
  75.   trayCont.appendChild(dotCont);
  76.  
  77.   var dots = [];
  78.  
  79.   props.trayParent.appendChild(trayCont);
  80.  
  81.   var firstItem = items[0];
  82.   var firstItemStyle = firstItem.currentStyle || window.getComputedStyle(firstItem);
  83.   var itemWidth = parseInt(firstItemStyle.getPropertyValue('margin-left')) + firstItem.offsetWidth + parseInt(firstItemStyle.getPropertyValue('margin-right'));
  84.   var fullWidth = items.length * itemWidth;
  85.   slider.style.width = fullWidth + 'px';
  86.  
  87.   var setItemsPerPage = function(newItemsPerPage) {
  88.     itemsPerPage = newItemsPerPage;
  89.     viewWidth = itemWidth * itemsPerPage;
  90.     maxLeft = -fullWidth + (itemWidth * itemsPerPage);
  91.     trayCont.style.width = viewWidth + 'px';
  92.     createDots();
  93.     updateLeft();
  94.   };
  95.  
  96.   var boundRightIncrement = function(left, newLeft) {
  97.     return left > maxLeft && left - viewWidth < maxLeft ? maxLeft : newLeft;
  98.   };
  99.  
  100.   var boundLeftIncrement = function(left, newLeft) {
  101.     return left < 0 && left + viewWidth > 0 ? 0 : newLeft
  102.   };
  103.  
  104.   var boundRightSet = function(left, newLeft) {
  105.     return left >= maxLeft && newLeft <= maxLeft ? maxLeft : newLeft;
  106.   };
  107.  
  108.   var updateLeft = function() {
  109.     var left = parseInt(slider.style.left);
  110.     var newLeft = left < maxLeft ? maxLeft : (left > 0 ? 0 : left);
  111.     if (typeof newLeft === 'number') {
  112.       newLeft = checkDot(newLeft);
  113.       animateLeft(newLeft);
  114.     }
  115.   };
  116.  
  117.   var removeSelectedDotClass = function() {
  118.     dots.forEach(function(dot) {
  119.       dot.className = dot.className.replace(selectedDotClassReg, '');
  120.     });
  121.   };
  122.  
  123.   var checkDot = function(newLeft) {
  124.     removeSelectedDotClass();
  125.     var nearLeft;
  126.     var nearDistance;
  127.     var nearDot;
  128.     for (var i = 0; i < dotAmount; i++) {
  129.       var dotLeft = getDotLeft(dots[i].getAttribute('pos-val'));
  130.       if (newLeft != dotLeft) {
  131.         var distance = Math.abs(newLeft - dotLeft);
  132.         if (typeof nearDistance !== 'number' || distance < nearDistance) {
  133.           nearLeft = dotLeft;
  134.           nearDistance = distance;
  135.           nearDot = i;
  136.         }
  137.         continue;
  138.       }
  139.       dots[i].className += ' ' + selectedDotClass;
  140.       return newLeft;
  141.     }
  142.     dots[nearDot].className += ' ' + selectedDotClass;
  143.     return nearLeft;
  144.   };
  145.   var animateLeft = function(newLeft) {
  146.     slider.style.left = newLeft + 'px';
  147.   };
  148.  
  149.   var createDots = function() {
  150.     dots = [];
  151.     dotAmount = items.length / itemsPerPage;
  152.     var dotContFragment = document.createDocumentFragment();
  153.     for (var i = 0; i < dotAmount; i++) {
  154.       var positionVal = (itemsPerPage * i);
  155.       var dot = createElement({
  156.         elementType: 'li',
  157.         className: (props.dotClass || 'dot') + (getDotLeft(positionVal) == parseInt(slider.style.left) ? ' ' + selectedDotClass : '')
  158.       });
  159.       dot.setAttribute('pos-val', positionVal);
  160.       dot.onclick = function() {
  161.         var dot = this;
  162.         removeSelectedDotClass();
  163.         dot.className += ' ' + selectedDotClass;
  164.         animateLeft(getDotLeft(dot.getAttribute('pos-val')));
  165.       };
  166.       dotContFragment.appendChild(dot);
  167.       dots[i] = dot;
  168.     }
  169.     while (dotCont.firstChild) {
  170.       dotCont.removeChild(dotCont.firstChild);
  171.     }
  172.     dotCont.appendChild(dotContFragment);
  173.   };
  174.  
  175.   var getDotLeft = function(positionVal) {
  176.     var newLeft = -(positionVal * itemWidth);
  177.     return boundRightSet(parseInt(slider.style.left), newLeft);
  178.   };
  179.  
  180.   var setItemsPerPageFromScreenWidth = function(tray) {
  181.     for (var i = 0; i < props.itemsPerPage.length; i++) {
  182.       var screenRange = props.itemsPerPage[i];
  183.       if ((typeof screenRange.min === 'number' && Math.min(screen.width, screenRange.min) != screenRange.min) || (typeof screenRange.max === 'number' && Math.max(screen.width, screenRange.max) != screenRange.max)) {
  184.         continue;
  185.       }
  186.       return setItemsPerPage(screenRange.items);
  187.     }
  188.   };
  189.   if (props.itemsPerPage instanceof Array) {
  190.     setItemsPerPageFromScreenWidth(props.itemsPerPage);
  191.   } else {
  192.     setItemsPerPage(typeof props.itemsPerPage === 'number' ? props.itemsPerPage : items.length);
  193.   }
  194. };
  195. var items = [{
  196.   'title': 'one'
  197. }, {
  198.   'title': 'two'
  199. }, {
  200.   'title': 'three'
  201. }, {
  202.   'title': 'four'
  203. }, {
  204.   'title': 'five'
  205. }, {
  206.   'title': 'six'
  207. }];
  208. var itemTemplate = function(item) {
  209.   var itemElement = document.createElement('section');
  210.   var title = document.createElement('h3');
  211.   title.textContent = item.title;
  212.   itemElement.appendChild(title);
  213.   itemElement.className = 'slide';
  214.   return itemElement;
  215. };
  216. var tray = new Tray({
  217.   trayParent: document.getElementById('tray'),
  218.   items: items,
  219.   itemTemplate: itemTemplate,
  220.   itemsPerPage: [{
  221.     min: 1024,
  222.     items: 3
  223.   }, {
  224.     min: 768,
  225.     max: 1024,
  226.     items: 2
  227.   }, {
  228.     max: 768,
  229.     items: 1
  230.   }]
  231. });
  232. var tray = new Tray({
  233.   trayParent: document.getElementById('tray'),
  234.   items: items,
  235.   itemTemplate: itemTemplate,
  236.   itemsPerPage: 1
  237. });