UNPKG

zz-shopify-components

Version:

Reusable Shopify components for theme projects

199 lines (191 loc) 6.39 kB
class WorldVideoDialog extends HTMLElement { isInitOpen = true; swiper = null; // swiper实例 constructor() { super(); this.init(); } init() { this.initData(); document.addEventListener('DOMContentLoaded', () => { this.initEvent(); }); } initEvent() { const closeBtn = this.querySelector('.close-modal-btn'); closeBtn.addEventListener('click', () => { this.closeModal(); }); } initData() { this.x1Img = this.dataset.x1Img; this.x1ProImg = this.dataset.x1proImg; this.x121Img = this.dataset.x121Img; this.x121Links = this.dataset.x121Links; this.x1Links = this.dataset.x1Links; this.x1ProLinks = this.dataset.x1proLinks; } // 初始化 initSwiper() { const swiperContainer = this.querySelector('.video-page-swiper'); if (swiperContainer) { const isDesktop = window.innerWidth >= 1024; this.swiper = new Swiper(swiperContainer, { direction: isDesktop ? 'horizontal' : 'vertical', navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, virtual: { slides: [], }, slidesPerView: 1, spaceBetween: 0, allowTouchMove: isDesktop ? false : true, // 禁用Swiper的触摸/拖动 preventInteractionOnTransition: false, touchStartPreventDefault: false, touchMoveStopPropagation: false, on: { slideChangeTransitionEnd: () => { this.handleVideoOnSlideChange(); }, slideChange: () => { const currentIndex = this.swiper.activeIndex; if (currentIndex === this.swiper.virtual.slides.length - 1) { // 滑到最后一条,加载下一页数据 const wordList = document.querySelector('world-video-list'); if (wordList) { wordList.loadNextPage(); } } }, }, }); this.isInitOpen = true; } } handleVideoOnSlideChange() { // 暂停所有视频 this.parseVideo(); // 播放当前 active slide 中的视频 const activeSlide = this.querySelector('.swiper-slide-active'); const video = activeSlide.querySelector('.word-slide-lazy-video'); if (video) { video.play().catch((err) => { console.error('视频播放失败', err); video.pause(); }); } } parseVideo() { // 暂停所有视频 const allVideos = this.querySelectorAll('.word-slide-lazy-video'); allVideos.forEach((video) => { video.pause(); }); } updateSlide(data, productType, isInit = false) { const template = $('#video-swiper-slide').html(); if (isInit) { this.destroySwiper(); this.initSwiper(); } data.forEach((item) => { let replacedTemplate = template .replace(new RegExp('{video-url}', 'g'), item.videoUrl) .replace(new RegExp('{poster-url}', 'g'), item.pictureUrl) .replace( new RegExp('{avatar}', 'g'), item.userInfo && item.userInfo.avatar ) .replace( new RegExp('{nickname}', 'g'), item.userInfo && item.userInfo.nickname ) .replace(new RegExp('{content}', 'g'), item.content) .replace(new RegExp('{likeCount}', 'g'), item.likeCount) .replace(new RegExp('{commentCount}', 'g'), item.commentCount) .replace(new RegExp('{mediaId}', 'g'), item.id); if (productType === 1) { replacedTemplate = replacedTemplate .replace(new RegExp('{product-links}', 'g'), this.x1Links) .replace(new RegExp('{product-icon}', 'g'), this.x1Img) .replace(new RegExp('{product-type}', 'g'), '130'); } else if (productType === 4) { replacedTemplate = replacedTemplate .replace(new RegExp('{product-links}', 'g'), this.x1ProLinks) .replace(new RegExp('{product-icon}', 'g'), this.x1ProImg) .replace(new RegExp('{product-type}', 'g'), '141'); } else if (productType === 3) { replacedTemplate = replacedTemplate .replace(new RegExp('{product-links}', 'g'), this.x121Links) .replace(new RegExp('{product-icon}', 'g'), this.x121Img) .replace(new RegExp('{product-type}', 'g'), '121'); } this.swiper.virtual.slides.push(replacedTemplate); }); this.swiper.virtual.update(); } // 销毁 destroySwiper() { if (this.swiper) { // 完全销毁swiper,包括所有事件监听器和DOM元素 const swiperWrapper = this.querySelector('.swiper-wrapper'); if (!swiperWrapper) return; // 找到swiper-wrapper 清空 swiperWrapper.innerHTML = ''; this.swiper.destroy(true, true); this.swiper = null; } } // 虚拟列表播放视频 playVideo() { setTimeout(() => { this.handleVideoOnSlideChange(); }, 200); } showModal(videoIndex) { const modal = this.querySelector('#world-video-modal'); const mask = this.querySelector('#world-video-modalMask'); const body = document.body; modal.style.display = 'block'; mask.style.display = 'block'; setTimeout(() => { modal.classList.add('show'); }, 10); body.classList.add('modal-open'); window.zzLockBodyScroll && window.zzLockBodyScroll(); // 滑到固定位置 if (this.isInitOpen) { // 是否是初始化后第一次打开 videoIndex && this.swiper.slideTo(videoIndex); } else { this.swiper.slideTo(videoIndex); } this.isInitOpen = false; this.playVideo(); window.zzAnalytics && window.zzAnalytics.trackEvent('world_video_dialog_open', { timestamp: new Date().toISOString(), }); } closeModal() { const modal = this.querySelector('#world-video-modal'); const mask = this.querySelector('#world-video-modalMask'); const body = document.body; window.zzUnlockBodyScroll && window.zzUnlockBodyScroll(); modal.classList.remove('show'); setTimeout(() => { modal.style.display = 'none'; mask.style.display = 'none'; this.parseVideo(); }, 200); body.classList.remove('modal-open'); } closeTouchMove() { this.swiper.allowTouchMove = false; } openTouchMove() { this.swiper.allowTouchMove = true; } } customElements.define('world-video-dialog', WorldVideoDialog);