import { getWindow, getDocument } from 'ssr-window'; import { elementChildren } from '../../shared/utils.js'; export default function HashNavigation({ swiper, extendParams, emit, on }) { let initialized = false; const document = getDocument(); const window = getWindow(); extendParams({ hashNavigation: { enabled: false, replaceState: false, watchState: false } }); const onHashChange = () => { emit('hashChange'); const newHash = document.location.hash.replace('#', ''); const activeSlideHash = swiper.slides[swiper.activeIndex].getAttribute('data-hash'); if (newHash !== activeSlideHash) { const newIndex = swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${newHash}"], swiper-slide[data-hash="${newHash}"]`)[0]); if (typeof newIndex === 'undefined') return; swiper.slideTo(newIndex); } }; const setHash = () => { if (!initialized || !swiper.params.hashNavigation.enabled) return; if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) { window.history.replaceState(null, null, `#${swiper.slides[swiper.activeIndex].getAttribute('data-hash')}` || ''); emit('hashSet'); } else { const slide = swiper.slides[swiper.activeIndex]; const hash = slide.getAttribute('data-hash') || slide.getAttribute('data-history'); document.location.hash = hash || ''; emit('hashSet'); } }; const init = () => { if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return; initialized = true; const hash = document.location.hash.replace('#', ''); if (hash) { const speed = 0; for (let i = 0, length = swiper.slides.length; i < length; i += 1) { const slide = swiper.slides[i]; const slideHash = slide.getAttribute('data-hash') || slide.getAttribute('data-history'); if (slideHash === hash) { const index = swiper.getSlideIndex(slide); swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true); } } } if (swiper.params.hashNavigation.watchState) { window.addEventListener('hashchange', onHashChange); } }; const destroy = () => { if (swiper.params.hashNavigation.watchState) { window.removeEventListener('hashchange', onHashChange); } }; on('init', () => { if (swiper.params.hashNavigation.enabled) { init(); } }); on('destroy', () => { if (swiper.params.hashNavigation.enabled) { destroy(); } }); on('transitionEnd _freeModeNoMomentumRelease', () => { if (initialized) { setHash(); } }); on('slideChange', () => { if (initialized && swiper.params.cssMode) { setHash(); } }); }