0

I have a button that's fixed on the bottom right side of the page;

.btn-this{
 width: 313px;
 height: 61px;
 background-color: #ebb762;
 position: fixed;
 bottom: 0;
 right: 0;
 z-index: 99;
}

And so i wanted to change the position of the button from 'fixed' to 'relative' after scrolling at a certain point of the page;

Now at first i had this work out for me:

JQuery(function ($) {
    var masinfo = $(".btn-this");
    $(window).scroll(function () {
        var scroll = $(window).scrollTop();

        if (scroll >= 457) {
            masinfo.css('position', 'relative');
        } else {
            masinfo.css({
                position: 'fixed',
                bottom: '0'
            });
        }
    });
});

But then i did see that this was not a quality solution , since i would have to paste and change the code for each page, and it would never be smooth.

So i did check this two posts:
Check if a user has scrolled to the bottom

How could I add a class of "bottom" to "#sidebar" once it reaches the bottom of its parent container?

But then again , i couldn't make it work smoothly, the code works, but it executes a lot of time,

when using:

if ($(window).scrollTop() + $(window).height() > $(document).height() - 78) {
    console.log('bottom');
} 

the console logs "bottom" 11 times;

I tried using a debouncer, but i just didn't understand the concept or just didn't do it the right way;

Has anyone been able to do something like this?

Gangadhar Jannu
  • 4,136
  • 6
  • 29
  • 49
Simo
  • 57
  • 8

2 Answers2

0

I see 3 possible bottlenecks:

  1. global event listener($(window).scroll()) may be attached for several times(it can be if you have SPA where navigation does not reload page and each new page set up one more handler)
  2. scroll event handler occurs on each scroll event
  3. ... and handler freeze page until its ended - that's where passive event listeners come to rescue.

As for #2 you addressed this with debouncing but it's better to see your code(about exact debouncing logic). You may make it in wrong way so not only last event dispatch handler is called but every time(with some delay)

As for #3 jQuery does not support it yet so you need to use low-level addEventListener instead.

skyboyer
  • 22,209
  • 7
  • 57
  • 64
  • Here are three different Methods i've tried , all of them with the same conclusion, https://pastebin.com/UcZ6hCmb . At this point im really just copy/pasting code and modifying it trying to make it work ... – Simo Oct 08 '18 at 13:30
0

A debounce function limits the rate at which a function can fire. Read more about debounce function There is one more way you can improve the performance of animations/scroll that is requestAnimationFrame

so your function can be written as

JQuery(function ($) {
    var masinfo = $(".btn-this");
    $(window).scroll(function () {
        // If there's a timer, cancel it
        if (timeout) {
            window.cancelAnimationFrame(timeout);
        }
        // Setup the new requestAnimationFrame()
        timeout = window.requestAnimationFrame(function () {
            if ($(window).scrollTop() + $(window).height() > $(document).height() - 78) {
                console.log('bottom');
            }
        });
    });
});
Gangadhar Jannu
  • 4,136
  • 6
  • 29
  • 49