UNPKG

zz-shopify-components

Version:

Reusable Shopify components for theme projects

268 lines (246 loc) 10.4 kB
class WorldVideo extends HTMLElement { constructor() { super(); this.init(); } init() { this.initSiteJump(); // 初始化详情按钮 this.initCommentsAction(); this.initVideoAction(); this.initCloseModal(); } initSiteJump() { const productLinks = decodeURIComponent(this.dataset.productLinks).replace( /\+/g, ' ' ); // 去掉productLinks 里面 + 号 this.querySelectorAll('.world-video-learn-more').forEach((item) => { item.addEventListener('click', (event) => { const productType = event.currentTarget.getAttribute('data-product-type'); window.zzAnalytics && window.zzAnalytics.trackEvent('world_video_learn_more', { timestamp: new Date().toISOString(), productType: productType, }); }); bindSiteJump(item, productLinks); }); } initVideoAction() { const video = this.querySelector('.video-player'); const videoPlayBtn = this.querySelector('.video-play-btn'); const playPauseBtn = this.querySelector('.play-pause'); const progressBar = this.querySelector('.progress-bar'); const progressContainer = this.querySelector('.progress-container'); const controlsContainer = this.querySelector('.controls-container'); const volumeBtn = this.querySelector('.volume-btn'); const mbVolumeBtn = this.querySelector('.mb-word-video-volume-btn'); const currentTimeDisplay = this.querySelector('.current-time'); const totalTimeDisplay = this.querySelector('.total-time'); const overlay = this.querySelector('.overlay'); this.video = video; if (window.innerWidth > 1024) { // 播放/暂停 playPauseBtn.addEventListener('click', () => { if (video.paused) { video.play(); } else { video.pause(); } }); } else { overlay.addEventListener('click', () => { if (video.paused) { video.play(); } else { video.pause(); } }); videoPlayBtn.addEventListener('click', () => { video.play(); videoPlayBtn.style.display = 'none'; }); } // 进度条拖动功能 let isDragging = false; // 更新进度条 video.addEventListener('timeupdate', () => { if (isDragging) return; const progress = (video.currentTime / video.duration) * 100; progressBar.style.width = `${progress}%`; currentTimeDisplay.textContent = formatTime(video.currentTime); }); // 更新视频时间的函数 function updateVideoTime(e) { const rect = progressContainer.getBoundingClientRect(); const clientX = e.clientX || (e.touches && e.touches[0].clientX); const pos = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width)); video.currentTime = pos * video.duration; progressBar.style.width = `${pos * 100}%`; } // 鼠标事件 progressContainer.addEventListener('mousedown', (e) => { e.stopPropagation(); isDragging = true; progressContainer.classList.add('dragging'); overlay.classList.add('hidden'); updateVideoTime(e); }); progressContainer.addEventListener('mousemove', (e) => { // 阻止冒泡 e.stopPropagation(); if (!isDragging) return; updateVideoTime(e); }); document.addEventListener('mouseup', () => { progressContainer.classList.remove('dragging'); setTimeout(() => { overlay.classList.remove('hidden'); isDragging = false; }, 500); }); // 触摸事件 progressContainer.addEventListener('touchstart', (e) => { isDragging = true; progressContainer.classList.add('dragging'); overlay.classList.add('hidden'); updateVideoTime(e); }); document.addEventListener('touchmove', (e) => { if (!isDragging) return; e.preventDefault(); updateVideoTime(e); }); document.addEventListener('touchend', () => { progressContainer.classList.remove('dragging'); setTimeout(() => { overlay.classList.remove('hidden'); isDragging = false; }, 500); }); volumeBtn.addEventListener('click', (e) => { e.stopPropagation(); if (video.muted === false) { video.muted = true; } else { video.muted = false; } updateVolumeIcon(); }); mbVolumeBtn.addEventListener('click', (e) => { e.stopPropagation(); if (video.muted === false) { video.muted = true; } else { video.muted = false; } updateVolumeIcon(); }); function updateVolumeIcon() { let volumeIcon = ''; if (video.muted) { volumeIcon = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12.7271 6.92578C13.7191 7.58537 14.3729 8.71327 14.3729 9.99388C14.3729 11.2745 13.7191 12.4024 12.7271 13.062" stroke="white" stroke-width="1.15381" stroke-linecap="round"/> <path d="M14.7729 4.91113C16.4168 6.00409 17.5001 7.87303 17.5001 9.99501C17.5001 12.117 16.4168 13.9859 14.7729 15.0789" stroke="white" stroke-width="1.15381" stroke-linecap="round"/> <path d="M3.50098 3.79785L15.8753 16.1722" stroke="white" stroke-width="1.25" stroke-linecap="round"/> <path d="M10 12.5468V16.4891C9.9997 17.1018 9.25411 17.4031 8.82812 16.9628L5.22754 13.2372H1.93164C1.5553 13.2371 1.25022 12.9319 1.25 12.5555V7.43153C1.25 7.05503 1.55517 6.74997 1.93164 6.74988H4.20312L10 12.5468ZM8.82812 3.0243C9.25423 2.58404 10 2.88606 10 3.49891V10.4257L5.76562 6.19129L8.82812 3.0243Z" fill="white"/> </svg> `; } else { volumeIcon = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M1.25 7.43155C1.25 7.05501 1.55525 6.74976 1.9318 6.74976H5.2272L8.82779 3.02494C9.25384 2.58419 9.9998 2.8858 9.9998 3.49881V16.4891C9.9998 17.1021 9.25375 17.4037 8.82773 16.9629L5.2272 13.2373H1.9318C1.55525 13.2373 1.25 12.932 1.25 12.5555V7.43155Z" fill="white"/> <path d="M12.7271 6.92578C13.7191 7.58537 14.3729 8.71327 14.3729 9.99388C14.3729 11.2745 13.7191 12.4024 12.7271 13.062" stroke="white" stroke-width="1.15381" stroke-linecap="round"/> <path d="M14.7729 4.91016C16.4168 6.00311 17.5001 7.87205 17.5001 9.99403C17.5001 12.116 16.4168 13.9849 14.7729 15.0779" stroke="white" stroke-width="1.15381" stroke-linecap="round"/> </svg> `; } mbVolumeBtn.innerHTML = volumeIcon; volumeBtn.innerHTML = volumeIcon; } // 格式化时间 function formatTime(seconds) { const minutes = Math.floor(seconds / 60); seconds = Math.floor(seconds % 60); return `${minutes}:${seconds.toString().padStart(2, '0')}`; } // 设置总时长 video.addEventListener('loadedmetadata', () => { totalTimeDisplay.textContent = formatTime(video.duration); updateVolumeIcon(); }); video.addEventListener('loadeddata', () => { if (video.duration) { totalTimeDisplay.textContent = formatTime(video.duration); } }); // 播放时添加样式 video.addEventListener('play', () => { videoPlayBtn.style.display = 'none'; playPauseBtn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <rect x="6.6001" y="5.09961" width="3.6" height="13.8" rx="0.9" fill="white"/> <rect x="13.7998" y="5.09961" width="3.6" height="13.8" rx="0.9" fill="white"/> </svg>`; }); // 暂停时添加样式 video.addEventListener('pause', () => { if (window.innerWidth < 1024) { videoPlayBtn.style.display = 'block'; } playPauseBtn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M19.2216 10.4612C20.3819 11.159 20.3819 12.841 19.2216 13.5388L10.2294 18.9463C9.03257 19.666 7.50836 18.804 7.50836 17.4075L7.50836 6.59251C7.50836 5.19597 9.03257 4.33398 10.2294 5.05368L19.2216 10.4612Z" fill="white"/> </svg>`; }); // 添加视频错误处理 video.addEventListener('error', (e) => { console.error('视频加载错误:', e); if (window.innerWidth < 1024) { videoPlayBtn.style.display = 'block'; } playPauseBtn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M19.2216 10.4612C20.3819 11.159 20.3819 12.841 19.2216 13.5388L10.2294 18.9463C9.03257 19.666 7.50836 18.804 7.50836 17.4075L7.50836 6.59251C7.50836 5.19597 9.03257 4.33398 10.2294 5.05368L19.2216 10.4612Z" fill="white"/> </svg>`; }); // 确保视频加载完成后设置总时长 if (video.readyState >= 2) { totalTimeDisplay.textContent = formatTime(video.duration); } } initCloseModal() { const closeBtn = this.querySelector('.mb-close-modal-btn'); closeBtn.addEventListener('click', () => { document.querySelector('world-video-dialog').closeModal(); }); } initCommentsAction() { const commentBtns = this.querySelectorAll('.video-comments-btn'); if (commentBtns) { commentBtns.forEach((item) => { item.addEventListener('click', (event) => { event.stopPropagation(); const id = event.currentTarget.getAttribute('data-id'); const dialog = this.querySelector('world-video-comments-dialog'); if (dialog) { dialog.showModal(id); } window.zzAnalytics && window.zzAnalytics.trackEvent('world-video-comments', { timestamp: new Date().toISOString(), }); }); }); } const likeBtns = this.querySelectorAll('.video-like-btn'); if (likeBtns) { likeBtns.forEach((item) => { item.addEventListener('click', (event) => { event.stopPropagation(); window.zzAnalytics && window.zzAnalytics.trackEvent('world-video-like', { timestamp: new Date().toISOString(), }); }); }); } } } customElements.define('world-video', WorldVideo);