1

I have this function:

        is_bottom: function() {
            if (settings.scrollBottomOffset === -1) {
                return false;
            } else {
                var scroll_height, scroll_top, height;
                scroll_height = self[0].scrollHeight;
                scroll_top = self.scrollTop();
                height = self[0].offsetHeight;
                var limit = scroll_height - settings.scrollBottomOffset;
                return scroll_top + height > limit;
            }
        }

I call this function before I render the html to check if my content is at bottom so I should move the scrollbar on element to bottom, after I've added new content.

The problem is that it's causing reflow that I want to eliminate, because the function is causing double layout first when I call is_bottom and second after I've rendered new content.

I think that this will improve my code a bit in same cases where there is lot of rendering. Even mili seconds will make a difference.

So my question is this, is there any other way to check if scrollbar is at bottom? I can use any sentinel element and using css to position it until it's hidden (e.g. using visibility: hidden). Maybe using new itersection or resize observer, it can be performance improvement that's only accessed in few browsers.

EDIT: I've just realized that I can check if my content have scrollbar first. The code that is making re-render multiple times don't show scrollbar at all:

    function have_scrollbar() {
        return fill.outerWidth() !== self.outerWidth();
    }

the problem is that this also causing reflow, is there a way to check if element have scrollbar without casing reflow?

jcubic
  • 61,973
  • 54
  • 229
  • 402
  • You're trying to avoid adding a new content dynamically? or having an optimized scroll function will solve your problem? – Ahed Kabalan Dec 25 '19 at 14:37
  • @AhedKabalan I have two functions that causing reflow in each render I want to eliminate one of them so my render is faster. – jcubic Dec 25 '19 at 20:42
  • This link has examples: https://stackoverflow.com/q/4880381/2796249 – Ahed Kabalan Dec 25 '19 at 21:47
  • @AhedKabalan thanks, but that code is causing reflow. mine is working I have two elements one is inside element with scrollbar, my have_scrollbar is working but it also causing reflow. I want to find a way to do that without reflow using any tools. Or check if scrollbar is at bottom without causing reflow. – jcubic Dec 26 '19 at 12:48

2 Answers2

0

if I correctly understand your question - you can listen to scroll event on the body element, end in the event objcet that you get in the enevt handler you have some information about the scroll state.

Yosi Leibman
  • 386
  • 3
  • 16
  • From looking at scroll event it don't have any information about the scroll, so it's useless. But maybe I can check if scrollbar is at bottom in scroll event. – jcubic Dec 26 '19 at 12:53
  • you have window.scrollY (and scrollX). you need to check that every time user scrolls. this event will be triggered every time user scrolls – Yosi Leibman Dec 26 '19 at 14:41
  • It's for window scroll I need any element with scrollbar I've never said I want window. I should add this to the question. – jcubic Dec 26 '19 at 16:20
0

I've almost solved everything I need, I use interection observer and put dummy element at bottom of my scrollable element. According to MDN the API work with parent that have scrollbar. So I can detect if element is at bottom:

function bottom_detect(intersections) {
    console.log(intersections[0]);
    is_bottom_detected = intersections[0].intersectionRatio === 1;
}
function create_bottom_detect() {
    if (window.IntersectionObserver) {
        var marker = $('<div class="scroll-marker"/>').appendTo(self);
        is_bottom_observer = new IntersectionObserver(bottom_detect, {
            root: self[0],
            rootMargin: '0px',
            threshold: 1.0
        });
        is_bottom_observer.observe(marker[0]);
    }
}

and it seems that for 100% scroll to bottom it works fine. the marker only need height: 1px; and if you don't want that extra space you can also use margin-top: -1px.

jcubic
  • 61,973
  • 54
  • 229
  • 402