【问题标题】:Sticky scrollbar at bottom of table表格底部的粘性滚动条
【发布时间】:2018-02-07 22:05:42
【问题描述】:

我不确定“粘性”是否是这个术语,但有没有办法让 overflow:auto 的滚动条保持可见?

我有一个相当大的表格,我希望它可以水平滚动;但是,表格也相当高,因此当页面加载时,水平滚动条不在浏览器的视口内,因此很难判断表格是否可滚动。

<div style = 'width:900px;overflow:auto'>
    <table>
        <!-- Very large table here -->
    </table>
</div>

滚动条出现在表格下方,但不幸的是表格太高了,除非向下滚动,否则您看不到它。

即使表格离开屏幕,我也希望水平滚动条保持可见,可能固定在视口的底部。理想情况下,我希望只使用 CSS 或少量的 javascript。

【问题讨论】:

  • 这做得很好,我认为它适合你,因为它是一个可能的解决方案,值得一试:stackoverflow.com/questions/3934271/…
  • 看起来可以,但是两个水平滚动条似乎有点尴尬。不过,如果没有简单的方法来制作粘性滚动条,我想我会求助于它。
  • 我更新了另一个问题的小提琴,使其更加优胜,更多地了解这个问题:jsfiddle.net/TBnqw/2283

标签: css scrollbar overflow sticky


【解决方案1】:

这是http://jsfiddle.net/TBnqw/2288/的脚本

$(function($){
    var scrollbar = $('<div id="fixed-scrollbar"><div></div></div>').appendTo($(document.body));
    scrollbar.hide().css({
        overflowX:'auto',
        position:'fixed',
        width:'100%',
        bottom:0
    });
    var fakecontent = scrollbar.find('div');

    function top(e) {
        return e.offset().top;
    }

    function bottom(e) {
        return e.offset().top + e.height();
    }

    var active = $([]);
    function find_active() {
        scrollbar.show();
        var active = $([]);
        $('.fixed-scrollbar').each(function() {
            if (top($(this)) < top(scrollbar) && bottom($(this)) > bottom(scrollbar)) {
                fakecontent.width($(this).get(0).scrollWidth);
                fakecontent.height(1);
                active = $(this);
            }
        });
        fit(active);
        return active;
    }

    function fit(active) {
        if (!active.length) return scrollbar.hide();
        scrollbar.css({left: active.offset().left, width:active.width()});
        fakecontent.width($(this).get(0).scrollWidth);
        fakecontent.height(1);
        delete lastScroll;
    }

    function onscroll(){
        var oldactive = active;
        active = find_active();
        if (oldactive.not(active).length) {
            oldactive.unbind('scroll', update);
        }
        if (active.not(oldactive).length) {
            active.scroll(update);
        }
        update();
    }

    var lastScroll;
    function scroll() {
        if (!active.length) return;
        if (scrollbar.scrollLeft() === lastScroll) return;
        lastScroll = scrollbar.scrollLeft();
        active.scrollLeft(lastScroll);
    }

    function update() {
        if (!active.length) return;
        if (active.scrollLeft() === lastScroll) return;
        lastScroll = active.scrollLeft();
        scrollbar.scrollLeft(lastScroll);
    }

    scrollbar.scroll(scroll);

    onscroll();
    $(window).scroll(onscroll);
    $(window).resize(onscroll);
});

这是一个快速测试而不是一个完整的通用插件,但我认为这是一个好的开始

【讨论】:

    【解决方案2】:

    这是我的看法,@user2451227 几乎完美,但不适用于嵌套的溢出元素并且存在许多性能问题,因此我重写了它:

    $(function($){
        var fixedBarTemplate = '<div class="fixed-scrollbar"><div></div></div>';
        var fixedBarCSS = { display: 'none', overflowX: 'scroll', position: 'fixed',  width: '100%', bottom: 0 };
    
        $('.fixed-scrollbar-container').each(function() {
            var $container = $(this);
            var $bar = $(fixedBarTemplate).appendTo($container).css(fixedBarCSS);
    
            $bar.scroll(function() {
                $container.scrollLeft($bar.scrollLeft());
            });
    
            $bar.data("status", "off");
        });
    
        var fixSize = function() {
            $('.fixed-scrollbar').each(function() {
                var $bar = $(this);
                var $container = $bar.parent();
    
                $bar.children('div').height(1).width($container[0].scrollWidth);
                $bar.width($container.width()).scrollLeft($container.scrollLeft());
            });
    
            $(window).trigger("scroll.fixedbar");
        };
    
        $(window).on("load.fixedbar resize.fixedbar", function() {
            fixSize();
        });
    
        var scrollTimeout = null;
    
        $(window).on("scroll.fixedbar", function() { 
            clearTimeout(scrollTimeout);
            scrollTimeout = setTimeout(function() {
                $('.fixed-scrollbar-container').each(function() {
                    var $container = $(this);
                    var $bar = $container.children('.fixed-scrollbar');
    
                    if($bar.length && ($container[0].scrollWidth > $container.width())) {
                        var containerOffset = {top: $container.offset().top, bottom: $container.offset().top + $container.height() };
                        var windowOffset = {top: $(window).scrollTop(), bottom: $(window).scrollTop() + $(window).height() };
    
                        if((containerOffset.top > windowOffset.bottom) || (windowOffset.bottom > containerOffset.bottom)) {
                            if($bar.data("status") == "on") {
                                $bar.hide().data("status", "off");
                            }
                        } else {
                            if($bar.data("status") == "off") {
                                $bar.show().data("status", "on");
                                $bar.scrollLeft($container.scrollLeft());
                            }
                        }
                    } else {
                        if($bar.data("status") == "on") {
                            $bar.hide().data("status", "off");
                        }
                    }
                });
            }, 50);
        });
    
        $(window).trigger("scroll.fixedbar");
    });
    

    用法:fixed-scrollbar-container 类添加到水平溢出的元素中,然后包含此代码。如果容器更新或大小发生变化,请运行$(window).trigger("resize.fixedbar"); 更新栏。

    演示: http://jsfiddle.net/8zoks7wz/1/

    【讨论】:

      【解决方案3】:

      @Mahn - 我对以下函数进行了小幅更新:

      $('.fixed-scrollbar-container').each(function() {
      
          var container = jQuery(this);
      
          if (container[0].offsetWidth < container[0].scrollWidth) {
              var bar = jQuery(fixedBarTemplate).appendTo(container).css(fixedBarCSS);
      
              bar.scroll(function() {
                  container.scrollLeft(bar.scrollLeft());
              });
      
              bar.data("status", "off");    
          }
      });
      

      if 语句检查容器的 offsetWidth 是否小于 scrollWidth。否则,如果内容恰好小于容器,您还将获得一个固定的滚动条。我不喜欢滚动条功能失调,因此进行了此编辑。

      【讨论】:

      • 嗨,欢迎来到 Stack Overflow。如果这是对另一个答案的更新,您应该将其作为评论发布,而不是作为独立答案发布。继续努力,干杯。
      • @Cthulhu - 我还没有足够的代表来做这件事......我只能发表新帖子并评论我自己的帖子。
      【解决方案4】:

      如何限制包含 div 的高度,使其保持在 body 内?然后,您可以让表格在该 div 内滚动。

      在这里工作 jsfiddle:http://jsfiddle.net/fybLK/

      html, body {height: 100%; margin: 0; padding: 0;}
      div {
          width:500px;
          max-height: 100%;
          overflow:auto;
          background: steelblue;}
      table {
          width: 1000px;
          height: 1000px;
          color: #fff;}
      

      在这里,我将 html 和 body 设置为 100% 高度,以便可以调整包含 div 的大小。

      【讨论】:

      • 这是一个不错的选择,但如果可能的话,我宁愿不必添加垂直滚动条。话虽这么说,这个解决方案真的很简单,看起来还不错,所以我最终可能会选择这个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 2019-12-19
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      • 2016-07-10
      相关资源
      最近更新 更多