NoName
NoName

Reputation: 181

How to stop second event mousewheel before first ends

I've got code which make my window scroll from element to element. If I scroll my mousewheel a little bit it works correctly. But if I scroll faster I've got trouble.

var currentPosition = 1;
angular.element(document).on("mousewheel DOMMouseScroll", function (e) {
    e.preventDefault();
    e.stopPropagation();

    var isUp = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? true : false;

    if (isUp) {
        if (currentPosition > 0) {
            currentPosition--;
            setPoinerActive();
            $scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
        }
    }
    else {
        if (currentPosition < 3) {
            currentPosition++;
            setPoinerActive();
            $scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
        }
    }
});

Answer

function debounce(func, wait, immediate) {
            timeout = null;
            return function () {
                var context = this, args = arguments;
                clearTimeout(timeout);
                timeout = setTimeout(function () {
                    timeout = null;
                    if (!immediate) {
                        func.apply(context, args);
                    }
                }, wait);

                if (immediate && !timeout) {
                    func.apply(context, args);
                }
            };
        }

Upvotes: 1

Views: 922

Answers (1)

serdar.sanri
serdar.sanri

Reputation: 2228

This issue is called debouncing and you may find quite a bit different versions of it if you google. Basically it has been noticed by twitter when user scrolls down the page, an infinite scroll script was loading more content. But then they noticed by the time script triggers several times when you do it fast enough and causes memory leaks and page unresponsive. so they come up with this idea, debouncing. simply, you add a timer in your function before your run your original event, if timer still exists then you cancel your event. so when you scroll down instead of triggering onscroll event 20 times, with timeout, it triggers every x milisecond N times.

function debounce(func, wait, immediate) {
    var self = this;
    self.timeout = null;
    return function() {
        var context = this, args = arguments;
        clearTimeout(self.timeout);
        self.timeout = setTimeout(function() {
            self.timeout = null;
            if (!immediate) {
                func.apply(context, args);
            }
        }, wait);

        if (immediate && !self.timeout) {
            func.apply(context, args);
        }
    };
}

Then in your original event listener,

    angular.element(document).on("mousewheel DOMMouseScroll", debounce(function(e){
       e.preventDefault();
       e.stopPropagation();

       var isUp = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? true : false;

       if (isUp) {
            if (currentPosition > 0) {
                currentPosition--;
                setPoinerActive();
                $scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
            }
        }
        else {
            if (currentPosition < 3) {
                currentPosition++;
                setPoinerActive();
                $scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
            }
        }
    });
    }, 300));

Upvotes: 4

Related Questions