AutoPlay Tabs (with video duration)
unknown
html
a year ago
3.7 kB
18
Indexable
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script> <script> async function waitForVideos(videos) { const promises = [] for (const video of videos) { if (isNaN(video.duration)) { promises.push(new Promise((resolve) => video.addEventListener("loadedmetadata", (event) => { resolve(); }) )) } } return Promise.all(promises) } const init = async () => { const ACTIVE_TAB = "w--current"; let activeIndex = 0; let timeout; let tween; // Select the node that will be observed for mutations const tabsComponent = document.querySelector('[wb-data="tabs"]'); if (!tabsComponent) return; const tabsMenu = tabsComponent.querySelector('[wb-data="menu"]'); if (!tabsMenu) return; const tabsContent = tabsComponent.querySelector('[wb-data="content"]'); if (!tabsContent) return; const videos = tabsContent.querySelectorAll("video"); if (!videos) return; const loaders = tabsMenu.querySelectorAll('.loader'); await waitForVideos(videos); // fix for safari scrolling to tab on focus if (navigator.userAgent.includes("Safari")) { let tabLinks = tabsMenu.childNodes tabLinks.forEach( (tabLink) => (tabLink.focus = function() { const x = window.scrollX, y = window.scrollY; const f = () => { setTimeout(() => window.scrollTo(x, y), 1); tabLink.removeEventListener("focus", f); }; tabLink.addEventListener("focus", f); HTMLElement.prototype.focus.apply(this, arguments); }) ); } const animateLoader = (duration) => { console.log("Update tween", { activeIndex }) tween = gsap.fromTo( loaders[activeIndex], { width: "0%" }, { width: "100%", duration: duration, ease: "none" } ); }; const autoPlayTabs = () => { clearTimeout(timeout); const activeVideo = videos[activeIndex]; console.log("AutoPlayTabs init", { duration: activeVideo.duration, activeIndex }); activeVideo.currentTime = 0; if (tween) { tween.progress(0); tween.kill() } if (loaders.length > 0) { animateLoader(activeVideo.duration); } timeout = setTimeout(() => { console.log("Set timeout - update next index", { childElementCount: tabsMenu.childElementCount, activeIndex }) let nextIndex; if (activeIndex >= tabsMenu.childElementCount - 1) { nextIndex = 0; } else { nextIndex = activeIndex + 1; } const nextTab = tabsMenu.childNodes[nextIndex]; nextTab.click(); }, activeVideo.duration * 1000); }; autoPlayTabs(); // Options for the observer (which mutations to observe) const config = { attributes: true, subtree: true, attributeFilter: ["class"], }; // Callback function to execute when mutations are observed const callback = (mutationList, observer) => { for (const mutation of mutationList) { if (mutation.type === "attributes") { const target = mutation.target; if (target.classList.contains(ACTIVE_TAB)) { activeIndex = parseInt(target.id.slice(-1), 10); console.log({ activeIndex }); // auto play tabs autoPlayTabs(); } } } }; // Create an observer instance linked to the callback function const observer = new MutationObserver(callback); // Start observing the target node for configured mutations observer.observe(tabsComponent, config); }; document.addEventListener("DOMContentLoaded", init); </script>
Editor is loading...
Leave a Comment