AutoPlay Tabs (with video duration)
unknown
html
2 years ago
3.7 kB
24
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