runtime.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. ;(function(){
  2. 'use strict';
  3. const deck = document.querySelector('.deck');
  4. if (!deck) return;
  5. const slides = deck.querySelectorAll('.slide');
  6. const total = slides.length;
  7. // Insert slide numbers
  8. slides.forEach((sl, i) => {
  9. const footer = sl.querySelector('.slide-number');
  10. if (footer) {
  11. footer.dataset.current = i + 1;
  12. if (total > 1) footer.dataset.total = total;
  13. }
  14. sl.dataset.index = i;
  15. });
  16. let current = 0;
  17. let isAnimating = false;
  18. function goTo(idx){
  19. if(isAnimating) return;
  20. idx = Math.max(0, Math.min(idx, total - 1));
  21. if(idx === current) return;
  22. isAnimating = true;
  23. const dir = idx > current ? 1 : -1;
  24. slides.forEach((sl, i)=>{
  25. sl.classList.remove('is-active', 'is-prev');
  26. });
  27. slides[current].classList.add('is-prev');
  28. slides[idx].classList.add('is-active');
  29. current = idx;
  30. setTimeout(()=>{ isAnimating = false; }, 550);
  31. }
  32. function next(){ goTo(current + 1); }
  33. function prev(){ goTo(current - 1); }
  34. // Keyboard nav
  35. document.addEventListener('keydown', e=>{
  36. if(e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === ' ') { e.preventDefault(); next(); }
  37. if(e.key === 'ArrowLeft' || e.key === 'ArrowUp') { e.preventDefault(); prev(); }
  38. if(e.key === 'Home') goTo(0);
  39. if(e.key === 'End') goTo(total - 1);
  40. });
  41. // Click/tap nav
  42. deck.addEventListener('click', e=>{
  43. if(e.target.closest('.slide-inner')) return;
  44. if(e.target.closest('.deck-footer')) return;
  45. const w = deck.clientWidth;
  46. if(e.clientX > w * 0.6) next();
  47. else if(e.clientX < w * 0.4) prev();
  48. });
  49. // Touch support
  50. let tx = 0;
  51. deck.addEventListener('touchstart', e=>{ tx = e.changedTouches[0].clientX; }, {passive:true});
  52. deck.addEventListener('touchend', e=>{
  53. const dx = e.changedTouches[0].clientX - tx;
  54. if(Math.abs(dx) < 60) return;
  55. dx > 0 ? prev() : next();
  56. }, {passive:true});
  57. // Init first slide
  58. slides[0] && slides[0].classList.add('is-active');
  59. })();