jQuery Slider Scroll Update

User
jQuery(document).ready(function ($) {
let currentIndex = 0;
const slides = $(".slide");
const totalSlides = slides.length;
let isScrolling = false;
const sliderWrapper = $(".slider-wrapper");
const sliderContainer = $(".slider-container");

function updateSliderHeight() {
let slideHeight = window.innerHeight;
slides.css("height", slideHeight + "px");
}

function scrollToSection(index, updateHash = true) {
if (index >= 0 && index < totalSlides) {
isScrolling = true;
let offset = index * -window.innerHeight;
sliderWrapper.css("transform", `translate(-50%, ${offset}px)`);
slides.removeClass("active");
slides.eq(index).addClass("active");

if (updateHash) {
history.pushState(null, null, `#slide-${index + 1}`);
}

setTimeout(() => isScrolling = false, 800);
}
}

function isSliderInView() {
const rect = sliderContainer[0].getBoundingClientRect();
return rect.top < window.innerHeight && rect.bottom > 0;
}

function preventBodyScroll(event) {
if (sliderWrapper.is(":focus") && isSliderInView() && currentIndex < totalSlides – 1) {
event.preventDefault();
}
}

// Check if we have reached the last slide
function isLastSlide() {
return currentIndex === totalSlides – 1;
}

// Wheel event to scroll through slides
$(window).on("wheel", function (event) {
if (!sliderWrapper.is(event.target) && !sliderWrapper.has(event.target).length) return; // Ensure it is inside the slider-wrapper

if (!isSliderInView()) return;

if (isScrolling) return;

if (event.originalEvent.deltaY > 0) {
if (currentIndex < totalSlides – 1) {
event.preventDefault();
currentIndex++;
scrollToSection(currentIndex);
}
} else {
if (currentIndex > 0) {
event.preventDefault();
currentIndex–;
scrollToSection(currentIndex);
}
}
});

// Update slide from URL hash
function updateSlideFromHash() {
const hash = window.location.hash;
if (hash.startsWith("#slide-")) {
let index = parseInt(hash.replace("#slide-", "")) – 1;
if (!isNaN(index) && index >= 0 && index < totalSlides) {
currentIndex = index;
scrollToSection(currentIndex, false);
}
}
}

$(window).on("resize", function () {
updateSliderHeight();
scrollToSection(currentIndex, false);
});

// Restart the slider when mouse enters or focus is on the wrapper area
sliderWrapper.on("mouseenter focusin", function () {
// If the user is on the last slide, reset the slider to the first slide
if (isLastSlide()) {
currentIndex = 0; // Reset to first slide
scrollToSection(currentIndex);
}

// Add wheel event listener only when wrapper is focused
window.addEventListener("wheel", preventBodyScroll, { passive: false });
});

// Remove wheel event listener when focus is lost
sliderWrapper.on("focusout", function () {
// If at the last slide, allow body scroll
if (isLastSlide()) {
window.removeEventListener("wheel", preventBodyScroll);
}
});

// Make sure to reset the scroll prevention when the last slide is reached
$(window).on("wheel", function (event) {
if (isLastSlide()) {
window.removeEventListener("wheel", preventBodyScroll); // Allow body scroll on last slide
}
});

// Make slider-wrapper focusable if not already
sliderWrapper.attr("tabindex", "0");

updateSliderHeight();
updateSlideFromHash();
});
also make allow upward scroll when slides finsinhed

Assistant
Here's the updated version of your script that allows upward scrolling after reaching the last slide:

jQuery(document).ready(function ($) {
    let currentIndex = 0;
    const slides = $(".slide");
    const totalSlides = slides.length;
    let isScrolling = false;
    const sliderWrapper = $(".slider-wrapper");
    const sliderContainer = $(".slider-container");
    let lastSlideReached = false;

    function updateSliderHeight() {
        let slideHeight = window.innerHeight;
        slides.css("height", slideHeight + "px");
    }

    function scrollToSection(index, updateHash = true) {
        if (index >= 0 && index < totalSlides) {
            isScrolling = true;
            let offset = index * -window.innerHeight;
            sliderWrapper.css("transform", `translate(-50%, ${offset}px)`);
            slides.removeClass("active");
            slides.eq(index).addClass("active");

            if (updateHash) {
                history.pushState(null, null, `#slide-${index + 1}`);
            }

            setTimeout(() => isScrolling = false, 800);
        }
    }

    function isSliderInView() {
        const rect = sliderContainer[0].getBoundingClientRect();
        return rect.top < window.innerHeight && rect.bottom > 0;
    }

    function preventBodyScroll(event) {
        if (sliderWrapper.is(":focus") && isSliderInView() && !lastSlideReached) {
            event.preventDefault();
        }
    }

    function isLastSlide() {
        return currentIndex === totalSlides - 1;
    }

    $(window).on("wheel", function (event) {
        if (!sliderWrapper.is(event.target) && !sliderWrapper.has(event.target).length) return;

        if (!isSliderInView()) return;

        if (isScrolling) return;

        if (event.originalEvent.deltaY > 0) {
            if (currentIndex < totalSlides - 1) {
                event.preventDefault();
                currentIndex++;
                scrollToSection(currentIndex);
            } else {
                lastSlideReached = true;
            }
        } else {
            if (currentIndex > 0) {
                event.preventDefault();
                lastSlideReached = false;
                currentIndex--;
                scrollToSection(currentIndex);
            }
        }
    });

    function updateSlideFromHash() {
        const hash = window.location.hash;
        if (hash.startsWith("#slide-")) {
            let index = parseInt(hash.replace("#slide-", "")) - 1;
            if (!isNaN(index) && index >= 0 && index < totalSlides) {
                currentIndex = index;
                scrollToSection(currentIndex, false);
            }
        }
    }

    $(window).on("resize", function () {
        updateSliderHeight();
        scrollToSection(currentIndex, false);
    });

    sliderWrapper.on("mouseenter focusin", function () {
        if (isLastSlide()) {
            lastSlideReached = true;
        }
        window.addEventListener("wheel", preventBodyScroll, { passive: false });
    });

    sliderWrapper.on("focusout", function () {
        if (isLastSlide()) {
            window.removeEventListener("wheel", preventBodyScroll);
        }
    });

    $(window).on("wheel", function (event) {
        if (isLastSlide()) {
            lastSlideReached = true;
            window.removeEventListener("wheel", preventBodyScroll);
        } else {
            lastSlideReached = false;
        }
    });

    sliderWrapper.attr("tabindex", "0");

    updateSliderHeight();
    updateSlideFromHash();
});

### Changes and Fixes:
1. **Allow upward scrolling after the last slide**
– A new variable `lastSlideReached` is introduced to track when the last slide is reached.
– It is set to `true` when scrolling down to the last slide and `false` when scrolling back up.
– This ensures that once the last slide is reached, the user can scroll back up freely.

2. **Prevents unwanted scroll blocking**
– The `preventBodyScroll` function is now applied only when needed.
– The `wheel` event listener ensures scrolling is restored once the last slide is left.

Now, the slider allows free upward scrolling once the last slide is reached while keeping the smooth scrolling behavior intact. Let me know if you need further refinements! ๐Ÿš€

Leave a Comment

Your email address will not be published. Required fields are marked *