Липкая полоса прокрутки внизу стола

Я не уверен, что термин "липкий" - это термин для этого, но есть ли способ, чтобы полоса прокрутки от overflow:auto оставалась видимой?

У меня довольно большая таблица, которую я хочу прокручивать по горизонтали; однако таблица также довольно высока, поэтому, когда страница загружается, горизонтальная полоса прокрутки находится не в окне просмотра браузера, поэтому довольно сложно сказать, что таблица прокручивается вообще.

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

Полоса прокрутки отображается под таблицей, но, к сожалению, таблица настолько высока, что вы не видите ее, пока не прокрутите вниз.

Я хотел бы, чтобы горизонтальная полоса прокрутки оставалась видимой, даже если стол уходит с экрана, возможно, фиксируется в нижней части окна просмотра. В идеале я бы хотел сделать это, используя только CSS или минимальное количество javascript.

Ответ 1

Вот script для 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

Здесь мой take, @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

Как насчет ограничения высоты содержащегося div, чтобы он оставался внутри тела? Затем вы можете прокручивать таблицу внутри этого 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 содержал.

Ответ 4

@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. Кроме того, вы также получите фиксированную полосу прокрутки, если содержимое окажется меньше, чем контейнер. Мне не нравилось иметь дисфункциональную полосу прокрутки, поэтому это редактирование.