Advertisement
andreymal

b3d.org.ua ekSlider replacement

Jan 17th, 2016
314
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        b3d slider test
  3. // @namespace   http://andreymal.org/tabun/userscripts
  4. // @include     http://b3d.org.ua/forum/
  5. // @include     http://b3d.org.ua/forum/index.php
  6. // @version     1
  7. // @grant       none
  8. // ==/UserScript==
  9.  
  10. 'use strict';
  11.  
  12.  
  13. // TODO: это, очевидно, должно быть в css-файле :)
  14. var styles = [
  15. '.ekSliderBlock {',
  16. '    position: relative;',
  17. '}',
  18. '.ekSliderList {',
  19. '    color: white;',
  20. '    position: absolute;',
  21. '    top: 0px;',
  22. '    left: 0px;',
  23. '    transition-property: left;',
  24. '    transition-timing-function: ease;',
  25. '}',
  26. '.ekSliderList a, .ekSliderList a:visited, .ekSliderList a:hover {',
  27. '    color: inherit;',
  28. '    text-decoration: none;',
  29. '}',
  30. '.ekSliderLink, .ekSliderLink:visited {',
  31. '    display: inline-block;',
  32. '    background-color: white;',
  33. '    background-position: center center;',
  34. '    background-size: cover;',
  35. '    margin: 0;',
  36. '    padding: 0;',
  37. '    position: relative;',
  38. '    vertical-align: top;',
  39. '}',
  40. '.ekSliderInfo {',
  41. '    padding: 10px;',
  42. '    box-sizing: border-box;',
  43. '    margin: 0 auto;',
  44. '    width: 90%;',
  45. '    margin-top: 20px;',
  46. '    background-color: rgba(0, 100, 76, 0.4);',
  47. '    border-radius: 5px;',
  48. '    border-spacing: 0px;',
  49. '}',
  50. '.ekSliderInfo hr {',
  51. '    border: 0;',
  52. '    height: 1px;',
  53. '    background-image: linear-gradient(to right, rgba(250, 250, 250, 0), rgba(250, 250, 250, 0.75), rgba(250, 250, 250, 0));',
  54. '}',
  55. '.ekSliderAuthor {',
  56. '    position: absolute;',
  57. '    bottom: 10%;',
  58. '    right: 5%;',
  59. '    color: black;',
  60. '    display: block;',
  61. '    text-shadow: 0 0 1px rgba(255, 255, 255, 0.9);',
  62. '}',
  63. '.ekSliderBlock .ekSliderNavigate {',
  64. '    top: 90%;',
  65. '    display: block;',
  66. '    text-align: center;',
  67. '    /* Остальное родное */',
  68. '}',
  69. '.ekSliderBlock .ekSliderNavigate span {',
  70. '    float: none;',
  71. '    display: inline-block;',
  72. '}'
  73. ];
  74.  
  75. var s = document.createElement('style');
  76. s.textContent = styles.join('\n');
  77. document.head.appendChild(s);
  78. s = null;
  79.  
  80.  
  81. var EKSlider = function(container) {
  82.     this.container = container;
  83.     this.animDuration = 500;
  84.     // TODO: поменять это на идеологически верный dataset
  85.     this.scrollDelay = parseInt(container.getAttribute('scrolldelay'));
  86.     this.size = parseInt(container.getAttribute('width'));
  87.  
  88.     this.currentItem = null;       // Текущий отображаемый элемент
  89.     this.itemsCount = 0;           // Общее число элементов
  90.     this.listElem = null;          // DOM-контейнер с элементами
  91.     this.navElem = null;           // DOM-контейнер с кнопками-переключалкам элементов
  92.     this.changeIntervalId = null;  // ID таймера, прокручивающего элементы
  93.     this.paused = false;           // Приостановлен ли таймер, переключающий элементы
  94.     this._overEventCurrent = null;
  95.     this._outEventCurrent = null;
  96.  
  97.     // Загружаем данные и запускаем слайдер
  98.     var x = new XMLHttpRequest();
  99.     x.open('POST', this.container.getAttribute('getfrom'));
  100.     x.onload = function() {
  101.         this.start(JSON.parse(x.responseText));
  102.     }.bind(this);
  103.     x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  104.     x.send('forSlider=1');
  105. };
  106.  
  107.  
  108. EKSlider.prototype.start = function(data) {
  109.     // При наведении мыши приостанавлимаем автоматическую прокрутку
  110.     this._overEventCurrent = this._mouseOverEvent.bind(this);
  111.     this._outEventCurrent = this._mouseOutEvent.bind(this);
  112.     this.container.addEventListener('mouseover', this._overEventCurrent);
  113.     this.container.addEventListener('mouseout', this._outEventCurrent);
  114.  
  115.     // Контейнер для блоков конкурса
  116.     var list = document.createElement('div');
  117.     list.className = 'ekSliderList';
  118.     list.style.width = (this.size * this.itemsCount) + 'px';
  119.     list.style.transitionDuration = this.animDuration + 'ms';
  120.     this.listElem = list;
  121.  
  122.     // Кнопочки навигации
  123.     var nav = document.createElement('div');
  124.     nav.className = 'ekSliderNavigate';
  125.     nav.addEventListener('click', this._btnClickEvent.bind(this));
  126.     this.navElem = nav;
  127.  
  128.     data.forEach(this.addItem.bind(this)); // Добавляем элементы
  129.  
  130.     this.container.appendChild(list);
  131.     this.container.appendChild(nav);
  132.     this.changeIntervalId = setInterval(this.next.bind(this), this.scrollDelay + this.animDuration);
  133. };
  134.  
  135.  
  136. EKSlider.prototype.addItem = function(item) {
  137.     // В ссылку кладём всё
  138.     var elem = document.createElement('a');
  139.     elem.className = 'ekSliderLink';
  140.     elem.style.width = this.size + 'px';
  141.     elem.style.height = this.size + 'px';
  142.     elem.style.backgroundImage = 'url("' + item[2] + '")';
  143.     elem.href = item[0];
  144.  
  145.     // Верхний блок с информацией
  146.     var infoBlock = document.createElement('div');
  147.     infoBlock.className = 'ekSliderInfo';
  148.  
  149.     // Название конкурса
  150.     var title = document.createElement('strong');
  151.     title.textContent = item[1];
  152.  
  153.     // Текущая тема конкурса
  154.     var theme = document.createElement('p');
  155.     var em = document.createElement('em');
  156.     em.textContent = 'Прием работ на тему: «' + item[3] + '»';
  157.     theme.appendChild(em);
  158.  
  159.     // Автор работы на фоне
  160.     var author = document.createElement('em');
  161.     author.className = 'ekSliderAuthor';
  162.     author.textContent = item[4];
  163.  
  164.     infoBlock.appendChild(title);
  165.     infoBlock.appendChild(document.createElement('hr'));
  166.     infoBlock.appendChild(theme);
  167.  
  168.     elem.appendChild(infoBlock);
  169.     elem.appendChild(author);
  170.  
  171.     this.listElem.appendChild(elem);
  172.  
  173.     // Кнопочка с навигацией
  174.     var btn = document.createElement('span');
  175.     btn.dataset.item = this.itemsCount;
  176.     this.navElem.appendChild(btn);
  177.  
  178.     // Проверяем счётчик
  179.     if (this.itemsCount === 0) {
  180.         this.currentItem = 0;
  181.         // TODO: поменять на btn.classList.add('shown');
  182.         btn.setAttribute('shown', 'true');
  183.     }
  184.     this.itemsCount++;
  185.  
  186.     // Корректируем длину контейнера
  187.     this.listElem.style.width = (this.itemsCount * this.size) + 'px';
  188. };
  189.  
  190.  
  191. EKSlider.prototype.next = function() {
  192.     if (!this.paused) {
  193.         this.set(this.currentItem >= (this.itemsCount - 1) ? 0 : this.currentItem + 1);
  194.     }
  195. };
  196.  
  197.  
  198. EKSlider.prototype.set = function(i) {
  199.     if (i < 0 || i >= this.itemsCount) {
  200.         return false;
  201.     }
  202.  
  203.     if (this.currentItem === i) {
  204.         return true;
  205.     }
  206.  
  207.     // TODO: поменять на this.navElem.children[this.currentItem].classList.remove('shown');
  208.     this.navElem.children[this.currentItem].removeAttribute('shown');
  209.     this.currentItem = i;
  210.     // TODO: поменять на this.navElem.children[this.currentItem].classList.add('shown');
  211.     this.navElem.children[this.currentItem].setAttribute('shown', 'true');
  212.     this.listElem.style.left = (-this.size * this.currentItem) + 'px';
  213.  
  214.     return true;
  215. };
  216.  
  217.  
  218. EKSlider.prototype.destroy = function() {
  219.     if (this.changeIntervalId !== null) {
  220.         clearInterval(this.changeIntervalId);
  221.         this.changeIntervalId = null;
  222.     }
  223.     if (this.listElem !== null) {
  224.         (this.listElem.parentNode || this.listElem.parentElement).removeChild(this.listElem);
  225.         this.listElem = null;
  226.     }
  227.     if (this.navElem !== null) {
  228.         (this.navElem.parentNode || this.navElem.parentElement).removeChild(this.navElem);
  229.         this.navElem = null;
  230.     }
  231.     this.itemsCount = 0;
  232.     this.currentItem = null;
  233.     this.paused = true;
  234.    
  235.     this.container.removeEventListener('mouseover', this._overEventCurrent);
  236.     this.container.removeEventListener('mouseout', this._outEventCurrent);
  237.     this._overEventCurrent = null;
  238.     this._outEventCurrent = null;
  239. };
  240.  
  241.  
  242. EKSlider.prototype._btnClickEvent = function(event) {
  243.     var i = (event.target || event.srcElement).dataset.item;
  244.     if (!i) {
  245.         return true;
  246.     }
  247.     this.set(parseInt(i));
  248.     return false;
  249. };
  250.  
  251.  
  252. EKSlider.prototype._mouseOverEvent = function() {
  253.     this.paused = true;
  254. };
  255.  
  256.  
  257. EKSlider.prototype._mouseOutEvent = function() {
  258.     this.paused = false;
  259. };
  260.  
  261.  
  262. // TODO: поменять load на DOMContentLoaded
  263. window.addEventListener('load', function() {
  264.     window.ekSlider = new EKSlider(document.querySelector('.ekSliderBlock'));
  265. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement