Wheel scroll slider fix

User
if ($('.overlay-slider-grid').length) {
const $overlaySliderGrid = $('.overlay-slider-grid');
const $overlayslider = $('.overlay-slider');
const $mainparent = $overlaySliderGrid.find('.content-overlayslider');
const $hoverItems = $mainparent.find('.hover-item');

let currentIndex = 0;
let isVisible = false; // Flag from intersection observer

const updateSlider = ($item) => {
const newBg = $item.data('bg');
$overlayslider.css('background-image', `url(${newBg})`);
$item.find('.content, .description').addClass('active');
$item.siblings().find('.content, .description').removeClass('active');
};

let lastDirection = null;
let isScrolling = false;

let accumulatedDelta = 0;
const scrollThreshold = 30; // Lower = more sensitive

$mainparent[0].addEventListener('wheel', function (e) {
if (!isVisible) return;

const delta = e.deltaY;

// Only act on meaningful scroll directions
if (delta > 0 && currentIndex < $hoverItems.length – 1) {
currentIndex++;
updateSlider($hoverItems.eq(currentIndex));
} else if (delta < 0 && currentIndex > 0) {
currentIndex–;
updateSlider($hoverItems.eq(currentIndex));
}

// Always prevent default scroll behavior
e.preventDefault();
}, { passive: false });

// Keyboard navigation
$(document).on('keydown', function (e) {
if (!isVisible) return;

if (e.key === 'ArrowUp' && currentIndex > 0) {
currentIndex–;
updateSlider($hoverItems.eq(currentIndex));
} else if (e.key === 'ArrowDown' && currentIndex < $hoverItems.length – 1) {
currentIndex++;
updateSlider($hoverItems.eq(currentIndex));
}
});

// Intersection Observer to detect visibility
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
isVisible = true;
$mainparent.addClass('visible');
updateSlider($hoverItems.eq(currentIndex));
} else {
isVisible = false;
$mainparent.removeClass('visible');
}
});
}, {
root: null,
rootMargin: '0px',
threshold: 0.5
});

observer.observe($overlaySliderGrid[0]);

// Sync slide with scroll position
$(window).on('scroll', function () {
const scrollTop = $(window).scrollTop();
const overlayOffset = $overlaySliderGrid.offset().top;
const overlayHeight = $overlaySliderGrid.outerHeight();

if (scrollTop >= overlayOffset && scrollTop

Assistant
To make the slide change on **a single wheel movement**, you need to **debounce rapid scroll events** (so one deltaY movement = one slide), and avoid triggering multiple slide changes from momentum scroll or high sensitivity mouse wheels.

Here’s a cleaned-up version that guarantees **1 slide per wheel scroll** with cooldown:

if ($('.overlay-slider-grid').length) {
    const $overlaySliderGrid = $('.overlay-slider-grid');
    const $overlayslider = $('.overlay-slider');
    const $mainparent = $overlaySliderGrid.find('.content-overlayslider');
    const $hoverItems = $mainparent.find('.hover-item');

    let currentIndex = 0;
    let isVisible = false;
    let scrollCooldown = false; // Prevents rapid scrolls

    const updateSlider = ($item) => {
        const newBg = $item.data('bg');
        $overlayslider.css('background-image', `url(${newBg})`);
        $item.find('.content, .description').addClass('active');
        $item.siblings().find('.content, .description').removeClass('active');
    };

    const changeSlide = (direction) => {
        if (scrollCooldown) return;

        if (direction === 'down' && currentIndex < $hoverItems.length - 1) {
            currentIndex++;
            updateSlider($hoverItems.eq(currentIndex));
        } else if (direction === 'up' && currentIndex > 0) {
            currentIndex--;
            updateSlider($hoverItems.eq(currentIndex));
        }

        scrollCooldown = true;
        setTimeout(() => scrollCooldown = false, 500); // Adjust this delay if needed
    };

    $mainparent[0].addEventListener('wheel', function (e) {
        if (!isVisible) return;

        const delta = e.deltaY;
        if (delta > 0) {
            changeSlide('down');
        } else if (delta < 0) {
            changeSlide('up');
        }

        e.preventDefault();
    }, { passive: false });

    // Keyboard navigation
    $(document).on('keydown', function (e) {
        if (!isVisible) return;

        if (e.key === 'ArrowUp') {
            changeSlide('up');
        } else if (e.key === 'ArrowDown') {
            changeSlide('down');
        }
    });

    // Intersection Observer to detect visibility
    const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
            isVisible = entry.isIntersecting;
            $mainparent.toggleClass('visible', isVisible);

            if (isVisible) {
                updateSlider($hoverItems.eq(currentIndex));
            }
        });
    }, {
        root: null,
        rootMargin: '0px',
        threshold: 0.5
    });

    observer.observe($overlaySliderGrid[0]);

    // Scroll sync with page position
    $(window).on('scroll', function () {
        const scrollTop = $(window).scrollTop();
        const overlayOffset = $overlaySliderGrid.offset().top;
        const overlayHeight = $overlaySliderGrid.outerHeight();

        if (scrollTop >= overlayOffset && scrollTop <= overlayOffset + overlayHeight) {
            const relativeScroll = (scrollTop - overlayOffset) / overlayHeight;
            const newIndex = Math.floor(relativeScroll * $hoverItems.length);

            if (newIndex !== currentIndex && newIndex < $hoverItems.length) {
                currentIndex = newIndex;
                updateSlider($hoverItems.eq(currentIndex));
            }
        }
    });
}

### ✅ What this fixes:
– Only one slide per `wheel` event.
– Prevents accidental multiple slides from strong scrolling.
– Ensures navigation only when the section is visible.

Let me know if you want it to support horizontal scroll gestures too.

Leave a Comment

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