naveen
naveen

Reputation: 610

Triggering onwheel listener only once when scrolled


I am using jQuery mousewheel listener to detect the scroll event. With a threshold value, I made the code trigger the code once, but it doesn't work when the user scrolls fast.

My JavaScript code

var prevPosition = -1;
var scrollStatus = null;
var result = 0;
var elements = ["child1","child2","child3"];
var position = 0;
var isInProgress = false;
$('#parent').on('mousewheel', function(event, delta) {
            event.preventDefault();
            console.log(isInProgress);
            if(isInProgress)
                return;
            setTimeout(function(){
                isInProgress = true;
            var value = event.originalEvent.deltaY;
            result =  result + value;
            if(result > 500) {
                result = 0;
                console.log('scroll up');
                console.log(position);
                if(position<elements.length-1){
                    $("#"+elements[position]).hide();
                    position++;
                    $("#"+elements[position]).show();
                }
                else{
                    //alert('cae');
                    $("#child4").show();
                }
            } 
            else if( result < -500) {
                result = 0;
                console.log('scroll down');
                if(position>0){
                    $("#"+elements[position]).hide();
                    position--;
                    $("#"+elements[position]).show();
                }
            }
            isInProgress = false;
            },1000);
        });

But this doesn't work in most cases, Is there any standard way to achieve this?

Upvotes: 2

Views: 414

Answers (1)

naveen
naveen

Reputation: 610

After one day effort, finally found an elegant solution :

        var prevPosition = -1;
        var scrollStatus = null;
        var result = 0;
        var elements = ["child1","child2","child3"];
        var position = 0;
        var isInProgress = false;
        $('#parent').on('mousewheel', function(event, delta) {
            event.preventDefault();
            console.log(isInProgress);
            if(isInProgress)
                return;
            var value = event.originalEvent.deltaY;
            result =  result + value;
            if(result > 500) {
                isInProgress = true;
                result = 0;
                console.log('scroll up');
                console.log(position);
                if(position<elements.length-1){
                    $("#"+elements[position]).hide();
                    position++;
                    $("#"+elements[position]).show();
                }
                else{
                    $("#child4").show();
                }
                setTimeout(()=>{
                    isInProgress = false;
                },1000);
            } 
            else if( result < -500) {
                isInProgress = true;
                result = 0;
                console.log('scroll down');
                if(position>0){
                    $("#"+elements[position]).hide();
                    position--;
                    $("#"+elements[position]).show();
                }
                setTimeout(()=>{
                    isInProgress = false;
                },1000);
            }
        });

What went wrong?

The problem with my previous code was that the isInProgress state is set to True only after 1 second the user scrolls, but within that delay, many events are firing and isInProgress is failing to serve its purpose. Now I have updated the code such that isInProgress is set to true only if the threshold value is satisfied and again set it to false with a timeout of 1 second(acting as a locking mechanism), Hence it finally worked!!

Upvotes: 1

Related Questions