表格顶部和底部的水平滚动条


159

table我的页面很大。因此,我决定在表格底部放置一个水平滚动条。但我希望此滚动条也位于表的顶部。

我在模板中的内容是这样的:

<div style="overflow:auto; width:100%; height:130%">
<table id="data" style="width:100%">...</table>
</div>

仅在HTML和CSS中可以这样做吗?


1
stackoverflow.com/questions/2274627/… 我发现此解决方案很有用。
VARSHA DAS 2015年

Answers:


234

要在元素顶部模拟第二个水平滚动条,请在div具有水平滚动的元素上方放置一个“虚拟” ,刚好足以容纳滚动条。然后为虚拟元素和真实元素附加“ scroll”事件的处理程序,以在移动任一滚动条时使另一个元素同步。虚拟元素看起来像真实元素上方的第二个水平滚动条。

有关实时示例,请参见此小提琴

这是代码

HTML:

<div class="wrapper1">
  <div class="div1"></div>
</div>
<div class="wrapper2">
  <div class="div2">
    <!-- Content Here -->
  </div>
</div>

CSS:

.wrapper1, .wrapper2 {
  width: 300px;
  overflow-x: scroll;
  overflow-y:hidden;
}

.wrapper1 {height: 20px; }
.wrapper2 {height: 200px; }

.div1 {
  width:1000px;
  height: 20px;
}

.div2 {
  width:1000px;
  height: 200px;
  background-color: #88FF88;
  overflow: auto;
}

JS:

$(function(){
  $(".wrapper1").scroll(function(){
    $(".wrapper2").scrollLeft($(".wrapper1").scrollLeft());
  });
  $(".wrapper2").scroll(function(){
    $(".wrapper1").scrollLeft($(".wrapper2").scrollLeft());
  });
});

真是个好答案!非常感谢!:)因此我尝试使用您的示例,但是顶部的栏不起作用,并且当我尝试增加宽度时,滚动条消失了。知道为什么吗?
psoares

1
你得到它的工作?有关jQuery的更多信息,请参见api.jquery.com/scrollLeft (当然,您可以在不使用jQuery的情况下直接附加onscroll处理程序。)对于没有JS的用户,如果要正常降级,可以通过JS将虚拟div添加到DOM中。 。
StanleyH,2010年

1
是的,我可以使用它,我只将<script type =“ text / javascript” src =“ path”> </ script>添加到<head>。因此,每次添加jquery时,都必须添加@fudgey添加的jquery吗?抱歉,javascript和jquery仍然对我来说是中文
psoares 2010年

4
@StanleyH:如何设置div以自动获取表格内部的宽度?我不想手动指定div2的宽度,但希望它自动采用它包含的表的宽度。
sqlchild 2014年

3
@CodyGuldner:如何设置div以自动获取表格内部的宽度?我不想手动指定div2的宽度,但希望它自动采用它包含的表的宽度。
sqlchild 2014年

38

尝试使用jquery.doubleScroll插件

jQuery的:

$(document).ready(function(){
  $('#double-scroll').doubleScroll();
});

CSS:

#double-scroll{
  width: 400px;
}

HTML:

<div id="double-scroll">
  <table id="very-wide-element">
    <tbody>
      <tr>
        <td></td>
      </tr>
    </tbody>
  </table>
</div>

5
请参阅github.com/avianey/jqDoubleScroll以获取不需要jQueryUI的Pawel很棒的插件版本。
fatal_error

1
链接会导致一个未维护的GitHub,其中的阅读链接损坏了。还没有尝试过实际的js。
Paul Gorbas '18

19

首先,很好的答案,@ StanleyH。如果有人想知道如何制作具有动态宽度的双滚动容器:

的CSS

.wrapper1, .wrapper2 { width: 100%; overflow-x: scroll; overflow-y: hidden; }
.wrapper1 { height: 20px; }
.div1 { height: 20px; }
.div2 { overflow: none; }

js

$(function () {
    $('.wrapper1').on('scroll', function (e) {
        $('.wrapper2').scrollLeft($('.wrapper1').scrollLeft());
    }); 
    $('.wrapper2').on('scroll', function (e) {
        $('.wrapper1').scrollLeft($('.wrapper2').scrollLeft());
    });
});
$(window).on('load', function (e) {
    $('.div1').width($('table').width());
    $('.div2').width($('table').width());
});

html

<div class="wrapper1">
    <div class="div1"></div>
</div>
<div class="wrapper2">
    <div class="div2">
        <table>
            <tbody>
                <tr>
                    <td>table cell</td>
                    <td>table cell</td>
                    <!-- ... -->
                    <td>table cell</td>
                    <td>table cell</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

演示

http://jsfiddle.net/simo/67xSL/


3
使用$('.div1').width( $('.div1')[0].scrollWidth)获得的内容,当你没有特别使用如表容器有用的真正动宽度。@simo很棒的努力伙伴。
克莱恩·席尔瓦

为了明确起见,我还必须将代码更改为scrollWidth,以便我的代码能够正常工作,因为由于位于其中的服务器端动态内容,“ div2” div中的内容宽度是可变的。
AdamJones

15

没有JQuery(2017)

因为您可能不需要JQuery,所以这里是基于@StanleyH答案的有效Vanilla JS版本:

var wrapper1 = document.getElementById('wrapper1');
var wrapper2 = document.getElementById('wrapper2');
wrapper1.onscroll = function() {
  wrapper2.scrollLeft = wrapper1.scrollLeft;
};
wrapper2.onscroll = function() {
  wrapper1.scrollLeft = wrapper2.scrollLeft;
};
#wrapper1, #wrapper2{width: 300px; border: none 0px RED;
overflow-x: scroll; overflow-y:hidden;}
#wrapper1{height: 20px; }
#wrapper2{height: 100px; }
#div1 {width:1000px; height: 20px; }
#div2 {width:1000px; height: 100px; background-color: #88FF88;
overflow: auto;}
<div id="wrapper1">
    <div id="div1">
    </div>
</div>
<div id="wrapper2">
    <div id="div2">
    aaaa bbbb cccc dddd aaaa bbbb cccc 
    dddd aaaa bbbb cccc dddd aaaa bbbb 
    cccc dddd aaaa bbbb cccc dddd aaaa 
    bbbb cccc dddd aaaa bbbb cccc dddd
    </div>
</div>


在您不知道宽度的情况下,这实际上不是响应式的/动态的
失落的银器

是!它与@StanleyH的原始答案有相同的警告
rap-2-h

11

您可以使用jQuery插件来为您完成这项工作:

该插件将为您处理所有逻辑。


2
尽管此插件与suwala / jquery.doubleScroll插件具有相同的功能,但它具有更多选项,例如重新计算window.resize的宽度
IvanHušnjak2014年

1
也并不依赖于jQuery UI。
tribe84 2015年

1
我会推荐这个插件,它看起来像suwala / jquery.doubleScroll的改进版,并且对我有用
Russell England

首先,谢谢您的出色插件!但是我有一个滚动方向的问题:rtl。似乎它不正确地支持它。如果您中的任何一个javascript专家都知道如何解决,请在这里摆弄:jsfiddle.net/qsn7tupc/3请注意,它可以在Chrome中使用,但不能在其他浏览器中使用。
弗拉多

10

StanleyH的回答很好,但是有一个不幸的错误:单击滚动条的阴影区域不再跳转到您单击的选择。取而代之的是,滚动条的位置增加了一个很小且令人讨厌的增量。

经过测试:4个版本的Firefox(影响100%),4个版本的Chrome(影响50%)。

这是我的jsfiddle。您可以通过具有on / off(true / false)变量来解决此问题,该变量一次只允许一个onScroll()事件触发:

var scrolling = false;
$(".wrapper1").scroll(function(){
    if(scrolling) {
      scrolling = false;
      return true;
    }
    scrolling = true;
    $(".wrapper2")
        .scrollLeft($(".wrapper1").scrollLeft());
});
$(".wrapper2").scroll(function(){
    if(scrolling) {
      scrolling = false;
      return true;
    }
      scrolling = true;
    $(".wrapper1")
        .scrollLeft($(".wrapper2").scrollLeft());
});

问题行为与可接受的答案:

实际所需的行为:

那么,为什么会这样呢?如果您遍历代码,您将看到wrapper1调用wrapper2的scrollLeft,而wrapper2调用wrapper1的scrollLeft,并无限地重复此操作,因此,我们遇到了无限循环问题。或者更确切地说:用户的继续滚动与wrapperx的滚动调用发生冲突,发生事件冲突,并且最终结果是滚动条中没有跳跃。

希望这可以帮助其他人!


很好的解释!的确确实在做一个无限循环
艾哈迈德·阿布德

是的 非常感谢你的支持!对我有帮助。
Giang D.MAI,

3

链接滚动条是可行的,但是在编写方式上,它会创建一个循环,如果您单击较浅的滚动条的一部分并按住它(而不是拖动滚动条时),则会使大多数浏览器的滚动速度变慢。

我用一个标志修复它:

$(function() {
    x = 1;
    $(".wrapper1").scroll(function() {
        if (x == 1) {
            x = 0;
            $(".wrapper2")
                .scrollLeft($(".wrapper1").scrollLeft());
        } else {
            x = 1;
        }
    });


    $(".wrapper2").scroll(function() {
        if (x == 1) {
            x = 0;
            $(".wrapper1")
                .scrollLeft($(".wrapper2").scrollLeft());
        } else {
            x = 1;
        }
    });
});

这也解决了我在这里使用建议答案所遇到的问题。但是,这只能稍微缓解一下问题,如果您要滚动的距离足够大,则可能仍会出现步进/缓慢滚动。
丹·邓普

使用条件/标记,此解决方案可以很好地工作,并且测试符合您期望的行为,而无需在浏览器中应用JavaScript。
userabuser

3

基于@HoldOffHunger和@bobince答案的纯JavaScript解决方案

<div id="doublescroll">

function DoubleScroll(element) {
            var scrollbar= document.createElement('div');
            scrollbar.appendChild(document.createElement('div'));
            scrollbar.style.overflow= 'auto';
            scrollbar.style.overflowY= 'hidden';
            scrollbar.firstChild.style.width= element.scrollWidth+'px';
            scrollbar.firstChild.style.paddingTop= '1px';
            scrollbar.firstChild.appendChild(document.createTextNode('\xA0'));
            var running = false;
            scrollbar.onscroll= function() {
                if(running) {
                    running = false;
                    return;
                }
                running = true;
                element.scrollLeft= scrollbar.scrollLeft;
            };
            element.onscroll= function() {
                if(running) {
                    running = false;
                    return;
                }
                running = true;
                scrollbar.scrollLeft= element.scrollLeft;
            };
            element.parentNode.insertBefore(scrollbar, element);
        }

    DoubleScroll(document.getElementById('doublescroll'));

3

基于@StanleyH解决方案,我创建了一个AngularJS指令,演示上的jsfiddle

易于使用:

<div data-double-scroll-bar-horizontal> {{content}} or static content </div>

对于AngularJS开发人员


31
“不需要jQuery。” 是的,只是一个整体框架。没关系
PitaJ

2

据我所知,HTML和CSS不可能做到这一点。


嗯,这其实是我的想法。但我想已知如果有人这样做,要做到这一点的最好方式..
psoares

对于HTML和CSS,没有最佳方法。根本不可能。您需要使用其他技术(例如javascript)来获得这种功能。
Justus Romijn 2010年

1
您可以提供一些提示以开始寻找吗?
psoares 2010年

2
这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方发表评论。
SSA 2014年

2
@SSA确实回答了问题。问题是“这是否只能在HTML和CSS中进行?” 答案是“否”。
punkrockbuddyholly 2015年

2

在vanilla Javascript / Angular中,您可以这样操作:

scroll() {
    let scroller = document.querySelector('.above-scroller');
    let table = document.querySelector('.table');
    table.scrollTo(scroller.scrollLeft,0);
  }

HTML:

<div class="above-scroller" (scroll)="scroll()">
  <div class="scroller"></div>
</div>
<div class="table" >
  <table></table>
</div>

CSS:

.above-scroller  {
   overflow-x: scroll;
   overflow-y:hidden;
   height: 20px;
   width: 1200px
 }

.scroller {
  width:4500px;
  height: 20px;
}

.table {
  width:100%;
  height: 100%;
  overflow: auto;
}

1

扩展StanleyH的答案,并尝试找到所需的最低要求,这是我实现的:

JavaScript(从某处调用过一次$(document).ready()):

function doubleScroll(){
        $(".topScrollVisible").scroll(function(){
            $(".tableWrapper")
                .scrollLeft($(".topScrollVisible").scrollLeft());
        });
        $(".tableWrapper").scroll(function(){
            $(".topScrollVisible")
                .scrollLeft($(".tableWrapper").scrollLeft());
        });
}

HTML(注意宽度会改变滚动条的长度):

<div class="topScrollVisible" style="overflow-x:scroll">
    <div class="topScrollTableLength" style="width:1520px; height:20px">
    </div>
</div>
<div class="tableWrapper" style="overflow:auto; height:100%;">
    <table id="myTable" style="width:1470px" class="myTableClass">
...
    </table>

而已。


1

给所有有角度/本地人的粉丝,实现@simo的答案

HTML(不变)

<div class="top-scroll-wrapper">
    <div class="top-scroll"></div>
</div>

CSS(不变,宽度:90%是我想要的)

.top-scroll-wrapper { width: 90%;height: 20px;margin: auto;padding: 0 16px;overflow-x: auto;overflow-y: hidden;}
.top-scroll { height: 20px; }

JS(如onload)或ngAfterViewChecked(全部as用于TypeScript

let $topscroll = document.querySelector(".top-scroll") as HTMLElement
let $topscrollWrapper = document.querySelector(".top-scroll-wrapper") as HTMLElement
let $table = document.querySelectorAll('mat-card')[3] as HTMLElement

$topscroll.style.width = totalWidth + 'px'
$topscrollWrapper.onscroll = e => $table.scroll((e.target as HTMLElement).scrollLeft, 0)
$table.onscroll = e => $topscrollWrapper.scroll((e.target as HTMLElement).scrollLeft, 0)

0

如果在Webkit浏览器或移动浏览器上使用iscroll.js,则可以尝试:

$('#pageWrapper>div:last-child').css('top', "0px");

0

一个用于实现此目的的AngularJs指令:要使用它,请将CSS类double-hscroll添加到您的元素中。为此,您将需要jQuery和AngularJs。

import angular from 'angular';

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $compile) {
  $scope.name = 'Dual wielded horizontal scroller';
});

app.directive('doubleHscroll', function($compile) {
  return {
restrict: 'C',
link: function(scope, elem, attr){

  var elemWidth = parseInt(elem[0].clientWidth);

  elem.wrap(`<div id='wrapscroll' style='width:${elemWidth}px;overflow:scroll'></div>`); 
  //note the top scroll contains an empty space as a 'trick' 
  $('#wrapscroll').before(`<div id='topscroll' style='height:20px; overflow:scroll;width:${elemWidth}px'><div style='min-width:${elemWidth}px'> </div></div>`);

  $(function(){
    $('#topscroll').scroll(function(){
      $("#wrapscroll").scrollLeft($("#topscroll").scrollLeft());
    });
    $('#wrapscroll').scroll(function() {
      $("#topscroll").scrollLeft($("#wrapscroll").scrollLeft());
    });

  });  

}

  };


});

0

这是VueJS的示例

index.page

<template>
  <div>
    <div ref="topScroll" class="top-scroll" @scroll.passive="handleScroll">
      <div
        :style="{
          width: `${contentWidth}px`,
          height: '12px'
        }"
      />
    </div>
    <div ref="content" class="content" @scroll.passive="handleScroll">
      <div
        :style="{
          width: `${contentWidth}px`
        }"
      >
        Lorem ipsum dolor sit amet, ipsum dictum vulputate molestie id magna,
        nunc laoreet maecenas, molestie ipsum donec lectus ut et sit, aut ut ut
        viverra vivamus mollis in, integer diam purus penatibus. Augue consequat
        quis phasellus non, congue tristique ac arcu cras ligula congue, elit
        hendrerit lectus faucibus arcu ligula a, id hendrerit dolor nec nec
        placerat. Vel ornare tincidunt tincidunt, erat amet mollis quisque, odio
        cursus gravida libero aliquam duis, dolor sed nulla dignissim praesent
        erat, voluptatem pede aliquam. Ut et tellus mi fermentum varius, feugiat
        nullam nunc ultrices, ullamcorper pede, nunc vestibulum, scelerisque
        nunc lectus integer. Nec id scelerisque vestibulum, elit sit, cursus
        neque varius. Fusce in, nunc donec, volutpat mauris wisi sem, non
        sapien. Pellentesque nisl, lectus eros hendrerit dui. In metus aptent
        consectetuer, sociosqu massa mus fermentum mauris dis, donec erat nunc
        orci.
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      contentWidth: 1000
    }
  },
  methods: {
    handleScroll(event) {
      if (event.target._prevClass === 'content') {
        this.$refs.topScroll.scrollLeft = this.$refs.content.scrollLeft
      } else {
        this.$refs.content.scrollLeft = this.$refs.topScroll.scrollLeft
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.top-scroll,
.content {
  overflow: auto;
  max-width: 100%;
}
.top-scroll {
  margin-top: 50px;
}
</style>

height: 12px.. 上注意一下,我将其设置为12px,因此Mac用户也会注意到它。但是使用Windows,0.1像素就足够了


-1

滚动方向存在问题:rtl。似乎插件不正确支持它。这里是小提琴:小提琴

请注意,它在Chrome中可以正常运行,但在所有其他流行的浏览器中,顶部滚动条的方向仍保持左。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.