web-dev-qa-db-ja.com

テーブルの下部にある粘着性のあるスクロールバー

「スティッキー」がこの用語であるかどうかはわかりませんが、overflow:autoのスクロールバーを表示したままにする方法はありますか?

水平方向にスクロールできるようにしたい、かなり大きなテーブルがあります。ただし、テーブルもかなり高いため、ページが読み込まれると、水平スクロールバーがブラウザのビューポート内にないため、テーブルがスクロール可能であるかどうかを判断するのはかなり困難です。

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

スクロールバーはテーブルの下に表示されますが、残念ながらテーブルは非常に高いため、下にスクロールしないと表示されません。

テーブルが画面から外れた場合でも、水平スクロールバーを表示したままにしたいのですが、ビューポートの下部に固定されている可能性があります。理想的には、CSSのみまたは最小限のJavaScriptを使用してそれを実行したいと思います。

19
jedyobidan

これがそのためのスクリプトです 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);
});

完全な汎用プラグインというよりは簡単なテストですが、良いスタートだと思います

8
user2451227

これが私の見解です。@ 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

@ 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よりも小さいかどうかを調べます。それ以外の場合、コンテンツがコンテナよりも小さい場合は、固定スクロールバーも表示されます。機能しないスクロールバーが気に入らなかったので、この編集を行います。

1
J.T. Houtenbos

含まれている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のサイズを変更できるようにしました。

1
Daze