0

I'm using a debounce script as part of a conditional that will add some css to a side menu when a user scrolls a page beyond a certain amount of pixels and then hide the menu when they are a set amount of pixels from the bottom. The script works as intended for screen widths 992px and above (as per conditional if (debounce_bodyWidth >= 992)) but it is still executing for dimensions below this.

Is there something about $(window).scroll that means it is executed irrespective of conditionals?

(function ($) {
    contactDebounce = function () {
        var debounce_bodyWidth = $(window).width();
        if (debounce_bodyWidth >= 992) {
            $(window).scroll(function () {
                var distanceFromBottom = $(document).height() - $(this).scrollTop();

                if (distanceFromBottom <= 1200) {
                    $('.sticky-element').addClass('hide');
                } else if ($(this).scrollTop() >= 150) {
                    $('.sticky-element').removeClass('hide');
                    $('.sticky-element').css({
                        'position': 'fixed',
                        'top': '15px'
                    });
                } else if ($(this).scrollTop() < 150) {
                    $('.sticky-element').css({
                        'position': 'relative',
                        'top': '0'
                    });
                }
            });
        }
    }
    contactDebounce();
    $(window).on("debouncedresize", contactDebounce);
})(jQuery);
Liam
  • 27,717
  • 28
  • 128
  • 190
Luke
  • 67
  • 7
  • 2
    you are binding the scroll event everytime your window is greater than 992, so if you go to more than 992 then it will be bound (and fire) even when you go smaller than 992. You want to probably bind it once and then put the if condition inside the event – Pete Dec 14 '15 at 13:45
  • If you'd [debugged this code](http://stackoverflow.com/questions/988363/how-can-i-debug-my-javascript-code) you would of likely been able to discover this easily yourself. – Liam Dec 14 '15 at 13:46
  • Cheers Pete. Now that I look at it I see that. – Luke Dec 14 '15 at 14:07

1 Answers1

3

What you are doing is binding a function to $(window).scroll on page load if the bodyWidth >= 992, this condition is never run again as all that is run on scroll is inside the scroll function you have created.

EDIT: It has been pointed out in comments that this is run again, on debounced resize. The problem then is that the scroll function has already been set when the condition is true and is not unset when the condition becomes false. You can either unset the event and check again on resize or add the condition inside the event and stop running the check on resize.

Try this, adding the condition inside the event:

(function ($) {
    contactDebounce = function () {
        $(window).scroll(function () {

            var debounce_bodyWidth = $(window).width();
            if (debounce_bodyWidth >= 992) {
                var distanceFromBottom = $(document).height() - $(this).scrollTop();
                var stickyElement = $('.sticky-element');

                if (distanceFromBottom <= 1200) {
                    stickyElement.addClass('hide');
                } else if ($(this).scrollTop() >= 150) {
                    stickyElement.removeClass('hide');
                    stickyElement.css({
                        'position': 'fixed',
                        'top': '15px'
                    });
                } else if ($(this).scrollTop() < 150) {
                    stickyElement.css({
                        'position': 'relative',
                        'top': '0'
                    });
                }
            }
        });
    }

    contactDebounce();
})(jQuery);

Or this, unbind when smaller, rebind when bigger:

(function ($) {
    contactDebounce = function () {
        var debounce_bodyWidth = $(window).width();
        if (debounce_bodyWidth >= 992) {
            $(window).scroll(function () {
                var distanceFromBottom = $(document).height() - $(this).scrollTop();
                var stickyElement = $('.sticky-element');
                if (distanceFromBottom <= 1200) {
                    stickyElement.addClass('hide');
                } else if ($(this).scrollTop() >= 150) {
                    stickyElement.removeClass('hide');
                    stickyElement.css({
                        'position': 'fixed',
                        'top': '15px'
                    });
                } else if ($(this).scrollTop() < 150) {
                    stickyElement.css({
                        'position': 'relative',
                        'top': '0'
                    });
                }
            });
        }
        else
        {
            $(window).unbind('scroll');
        }
    }

    contactDebounce();
    $(window).on("debouncedresize", contactDebounce);
})(jQuery);
Dhunt
  • 1,584
  • 9
  • 22
  • Edited out the duplicate jQuery selector. It's a good practice to avoid unnecessary DOM traversing. – Dropout Dec 14 '15 at 13:49
  • Agreed, I had just looked at the problem, missed that. Thanks – Dhunt Dec 14 '15 at 13:50
  • I was too slow to point out the things you said, so I just wanted to be at least a bit helpful ;) – Dropout Dec 14 '15 at 13:50
  • "this condition is never run again" - it's run at startup and on every `$(window).debouncedresize()" - see @Pete 's comment on the OP. – freedomn-m Dec 14 '15 at 13:52
  • Yeah, that's the answer and it now makes perfect sense. Cheers to everyone (apart form Liam :P) – Luke Dec 14 '15 at 14:10