Having a Timeline on my Website using SwiperJS presents challenges with conflicting functions. The goal is to navigate swiper-slides by clicking on timespans in the timeline.
The desired functionality for the timeline includes:
- Sliding to the corresponding slide when clicking on a timespan, setting it as active and scrolling it into view.
init: function () {
const timeline = document.querySelectorAll(".timespan");
timeline.forEach(function (timespan) {
timespan.addEventListener("click", function () {
// Remove active class from all timespans
timeline.forEach(function (item) {
item.classList.remove("active");
});
// Add active class to the clicked timespan
timespan.classList.add("active");
// Scroll to the clicked timespan
scrollToTimespan(timespan);
// Slide to the corresponding slide
let slideIndex = parseInt(timespan.dataset.slideIndex);
timelineSwiper.slideTo(slideIndex);
});
});
},
- Setting the middle timespan in the viewport as active. So when scrolling the timeline, the centered timespan becomes active and displays its related slide.
const timespans = document.querySelectorAll(".timespan");
const scrollContainer = document.querySelector(".about .container");
let scrolling = false;
// Function to check if an element is in the middle of the viewport
function isElementInViewport(element) {
const rect = element.getBoundingClientRect();
const viewportHeight =
window.innerHeight || document.documentElement.clientHeight;
const middleViewport = viewportHeight / 2;
return rect.top <= middleViewport && rect.bottom >= middleViewport;
}
// Function to remove the active class from all timespan elements
function removeActiveClass() {
timespans.forEach((timespan) => {
timespan.classList.remove("active");
});
}
// Function to set the active class to the timespan element in the middle of the viewport
function setActiveClass() {
removeActiveClass();
timespans.forEach((timespan) => {
if (isElementInViewport(timespan)) {
timespan.classList.add("active");
const slideIndex = parseInt(timespan.dataset.slideIndex);
timelineSwiper.slideTo(slideIndex);
}
});
}
// Function to scroll the timespan into view
function scrollToTimespan(timespan) {
timespan.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "center",
});
}
// Call the setActiveClass function initially on window load and on scroll
window.addEventListener("load", setActiveClass);
scrollContainer.addEventListener("scroll", function () {
if (!scrolling) {
scrolling = true;
window.requestAnimationFrame(function () {
setActiveClass();
scrolling = false;
});
}
});
- Activating the corresponding timespan and scrolling it into view when dragging the swiper to the next or previous slide.
slideChange: function () {
if (!this.isBeginning && !this.isEnd) {
const timeline = document.querySelectorAll(".timespan");
const activeSlideIndex = timelineSwiper.activeIndex;
// Remove active class from all timespans
timeline.forEach(function (item) {
item.classList.remove("active");
});
// Add active class to the corresponding timespan of the active slide
timeline[activeSlideIndex].classList.add("active");
// Scroll to the corresponding timespan
const activeTimespan = timeline[activeSlideIndex];
scrollToTimespan(activeTimespan);
}
},
The above functions present conflicts, particularly with changing slides based on user interaction. Looking for suggestions on how to achieve the desired functionality mentioned.
Here is The code snippet: