Javascript 检查滚动条是否位于底部而不会导致回流

Javascript 检查滚动条是否位于底部而不会导致回流,javascript,html,css,performance,Javascript,Html,Css,Performance,我有这个功能: is_bottom: function() { if (settings.scrollBottomOffset === -1) { return false; } else { var scroll_height, scroll_top, height; scroll_height = self[0].scrollHeig

我有这个功能:

        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;
            }
        }
我在呈现html之前调用这个函数来检查我的内容是否在底部,所以在添加新内容之后,我应该将元素上的滚动条移到底部

问题是,它导致了我想要消除的回流,因为该函数首先在我调用is_bottom时导致双布局,然后在我呈现新内容后导致双布局

我认为这将在渲染量很大的情况下稍微改进我的代码。即使是微秒也会有所不同

所以我的问题是,有没有其他方法来检查滚动条是否在底部?我可以使用任何sentinel元素并使用css来定位它,直到它被隐藏为止(例如,使用
可见性:hidden
)。也许使用新的itersection或resize observer,它可以提高性能,只有在少数浏览器中才能访问

编辑: 我刚刚意识到我可以先检查我的内容是否有滚动条。多次重新渲染的代码根本不显示滚动条:

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

问题是这也会导致回流,有没有办法检查元素是否有滚动条而没有大小写回流?

如果我正确理解您的问题,您可以收听body元素上的滚动事件,在enevt处理程序中获得的事件objcet中结束。您有一些有关滚动状态的信息。

如果我正确理解您的问题,您可以收听body元素上的滚动事件,在enevt处理程序中获得的事件ObjSet中结束,您可以获得有关滚动状态的一些信息。

我几乎解决了所有需要的问题,我使用interection observer并将虚拟元素放在可滚动元素的底部。根据API,与具有滚动条的父项一起工作。因此,我可以检测元素是否位于底部:

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]);
    }
}
功能底部检测(交叉点){
console.log(交叉点[0]);
is_bottom_detected=交点[0]。交点比率===1;
}
函数create_bottom_detect(){
if(window.IntersectionObserver){
变量标记=$('').appendTo(self);
is_bottom_observer=新的IntersectionObserver(bottom_detect{
根:self[0],
rootMargin:'0px',
阈值:1.0
});
是底部观察者。观察(标记[0]);
}
}

看起来100%滚动到底部效果很好。标记器只需
高度:1px
如果您不需要额外的空间,您也可以使用
边距顶部:-1px

我几乎解决了所有需要的问题,我使用interection observer并将虚拟元素放在可滚动元素的底部。根据API,与具有滚动条的父项一起工作。因此,我可以检测元素是否位于底部:

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]);
    }
}
功能底部检测(交叉点){
console.log(交叉点[0]);
is_bottom_detected=交点[0]。交点比率===1;
}
函数create_bottom_detect(){
if(window.IntersectionObserver){
变量标记=$('').appendTo(self);
is_bottom_observer=新的IntersectionObserver(bottom_detect{
根:self[0],
rootMargin:'0px',
阈值:1.0
});
是底部观察者。观察(标记[0]);
}
}

看起来100%滚动到底部效果很好。标记器只需
高度:1px
如果您不需要额外的空间,您也可以使用
边距顶部:-1px

您试图避免动态添加新内容吗?或者使用优化的滚动函数可以解决您的问题?@AhedKabalan我有两个函数在每次渲染中都会导致回流,我想消除其中一个,这样我的渲染速度会更快。此链接有示例:@AhedKabalan谢谢,但该代码会导致回流。我的正在工作我有两个元素一个是内部元素与滚动条,我的有滚动条正在工作,但它也导致回流。我想找到一种方法来做到这一点,不回流使用任何工具。或者检查滚动条是否位于底部而不会导致回流。您是否试图避免动态添加新内容?或者使用优化的滚动函数可以解决您的问题?@AhedKabalan我有两个函数在每次渲染中都会导致回流,我想消除其中一个,这样我的渲染速度会更快。此链接有示例:@AhedKabalan谢谢,但该代码会导致回流。我的正在工作我有两个元素一个是内部元素与滚动条,我的有滚动条正在工作,但它也导致回流。我想找到一种方法来做到这一点,不回流使用任何工具。或者检查滚动条是否在底部,而不会导致回流。从滚动事件来看,它没有任何关于滚动的信息,因此它是无用的。但也许我可以在scroll事件中检查scrollbar是否位于底部。您有window.scrollY(和scrollX)。每次用户滚动时,您都需要检查。每次用户scrollsIt为WindowScroll我需要scrollbar中的任何元素时,都会触发此事件。我从未说过我需要window。我应该把这个添加到问题中。从滚动事件来看,它没有关于滚动的任何信息,所以它是无用的。但也许我可以在scroll事件中检查scrollbar是否位于底部。您有window.scrollY(和scrollX)。每次用户滚动时,您都需要检查。每次用户scrollsIt为WindowScroll我需要scrollbar中的任何元素时,都会触发此事件。我从未说过我需要window。我应该补充这一点。