history.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { getWindow } from 'ssr-window';
  2. export default function History(_ref) {
  3. let {
  4. swiper,
  5. extendParams,
  6. on
  7. } = _ref;
  8. extendParams({
  9. history: {
  10. enabled: false,
  11. root: '',
  12. replaceState: false,
  13. key: 'slides'
  14. }
  15. });
  16. let initialized = false;
  17. let paths = {};
  18. const slugify = text => {
  19. return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
  20. };
  21. const getPathValues = urlOverride => {
  22. const window = getWindow();
  23. let location;
  24. if (urlOverride) {
  25. location = new URL(urlOverride);
  26. } else {
  27. location = window.location;
  28. }
  29. const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
  30. const total = pathArray.length;
  31. const key = pathArray[total - 2];
  32. const value = pathArray[total - 1];
  33. return {
  34. key,
  35. value
  36. };
  37. };
  38. const setHistory = (key, index) => {
  39. const window = getWindow();
  40. if (!initialized || !swiper.params.history.enabled) return;
  41. let location;
  42. if (swiper.params.url) {
  43. location = new URL(swiper.params.url);
  44. } else {
  45. location = window.location;
  46. }
  47. const slide = swiper.slides.eq(index);
  48. let value = slugify(slide.attr('data-history'));
  49. if (swiper.params.history.root.length > 0) {
  50. let root = swiper.params.history.root;
  51. if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
  52. value = `${root}/${key}/${value}`;
  53. } else if (!location.pathname.includes(key)) {
  54. value = `${key}/${value}`;
  55. }
  56. const currentState = window.history.state;
  57. if (currentState && currentState.value === value) {
  58. return;
  59. }
  60. if (swiper.params.history.replaceState) {
  61. window.history.replaceState({
  62. value
  63. }, null, value);
  64. } else {
  65. window.history.pushState({
  66. value
  67. }, null, value);
  68. }
  69. };
  70. const scrollToSlide = (speed, value, runCallbacks) => {
  71. if (value) {
  72. for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
  73. const slide = swiper.slides.eq(i);
  74. const slideHistory = slugify(slide.attr('data-history'));
  75. if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) {
  76. const index = slide.index();
  77. swiper.slideTo(index, speed, runCallbacks);
  78. }
  79. }
  80. } else {
  81. swiper.slideTo(0, speed, runCallbacks);
  82. }
  83. };
  84. const setHistoryPopState = () => {
  85. paths = getPathValues(swiper.params.url);
  86. scrollToSlide(swiper.params.speed, swiper.paths.value, false);
  87. };
  88. const init = () => {
  89. const window = getWindow();
  90. if (!swiper.params.history) return;
  91. if (!window.history || !window.history.pushState) {
  92. swiper.params.history.enabled = false;
  93. swiper.params.hashNavigation.enabled = true;
  94. return;
  95. }
  96. initialized = true;
  97. paths = getPathValues(swiper.params.url);
  98. if (!paths.key && !paths.value) return;
  99. scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
  100. if (!swiper.params.history.replaceState) {
  101. window.addEventListener('popstate', setHistoryPopState);
  102. }
  103. };
  104. const destroy = () => {
  105. const window = getWindow();
  106. if (!swiper.params.history.replaceState) {
  107. window.removeEventListener('popstate', setHistoryPopState);
  108. }
  109. };
  110. on('init', () => {
  111. if (swiper.params.history.enabled) {
  112. init();
  113. }
  114. });
  115. on('destroy', () => {
  116. if (swiper.params.history.enabled) {
  117. destroy();
  118. }
  119. });
  120. on('transitionEnd _freeModeNoMomentumRelease', () => {
  121. if (initialized) {
  122. setHistory(swiper.params.history.key, swiper.activeIndex);
  123. }
  124. });
  125. on('slideChange', () => {
  126. if (initialized && swiper.params.cssMode) {
  127. setHistory(swiper.params.history.key, swiper.activeIndex);
  128. }
  129. });
  130. }