테이블 상단과 하단의 가로 스크롤 막대


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

답변:


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를 참조하십시오 (물론 onscroll 핸들러를 직접 연결하여 jQuery없이 수행 할 수 있습니다). .
StanleyH

1
예, 제대로 작동했습니다. <head>에 <script type = "text / javascript"src = "path"> </ script> 만 추가했습니다. 그래서 jquery를 추가 할 때마다 @ fudgey가 추가 한 것을 추가해야합니까? 죄송합니다, 자바 스크립트, JQuery와 나에게 친절 중국어의 여전히이
psoares

4
@ StanleyH : div 안에 테이블 너비를 자동으로 설정하는 방법은 무엇입니까? div2의 너비를 수동으로 지정하고 싶지 않지만 포함 된 테이블의 너비를 자동으로 가져 오기를 원합니다.
sqlchild

3
@CodyGuldner : div 안에 테이블 너비를 자동으로 설정하는 방법은 무엇입니까? div2의 너비를 수동으로 지정하고 싶지 않지만 포함 된 테이블의 너비를 자동으로 가져 오기를 원합니다.
sqlchild

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
jQueryUI가 필요하지 않은 Pawel의 멋진 플러그인 버전은 github.com/avianey/jqDoubleScroll 을 참조하십시오 .
fatal_error

1
링크가 끊어진 링크가있는 유지 관리되지 않은 GitHub로 연결됩니다. 실제 js를 시도하지 않았습니다.
Paul Gorbas

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 멋진 노력 친구.
Clain Dsilva

명확히하기 위해, 서버 측 동적 컨텐츠로 인해 "div2"div 내의 컨텐츠 너비가 가변적 인 코드가 작동하도록 scrollWidth로 코드를 변경해야했습니다.
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>


너비를 모르는 경우에는 실제로 반응이없고 역동적이지 않습니다.
elad silver

예! 원래 @StanleyH 의해 답변 같은주의 갖는다
랩 -2- H

11

작업을 수행하는 jQuery 플러그인을 사용할 수 있습니다.

플러그인은 모든 로직을 처리합니다.


2
이 플러그인은 같은 일을하지만 suwala / jquery.doubleScroll 플러그인은 window.resize에 폭을 재 계산하는 등 더 많은 옵션이 있습니다
이반 Hušnjak을

1
또한 jquery UI에 의존하지 않습니다.
tribe84

1
이 플러그인을 추천합니다. suwala / jquery.doubleScroll의 개선 된 버전처럼 보이고 저에게 효과적입니다.
Russell England

먼저 훌륭한 플러그인에 감사드립니다! 그러나 스크롤 방향에 문제가 있습니다 : rtl. 제대로 지원하지 않는 것 같습니다. javascripts 전문가 중 누구든지 여기에 문제를 해결하는 방법을 알고 있다면 바이올린이 있습니다 : jsfiddle.net/qsn7tupc/3 Chrome에서는 작동하지만 다른 브라우저에서는 작동하지 않습니다.
Vlado

10

StanleyH의 답변은 훌륭했지만 불행한 버그가있었습니다. 스크롤바의 음영 영역을 클릭해도 더 이상 클릭 한 항목으로 이동하지 않습니다. 대신, 당신이 얻는 것은 스크롤 막대의 위치가 매우 작고 다소 성가신 증가입니다.

테스트 : 4 가지 버전의 Firefox (100 % 영향), 4 가지 버전의 Chrome (50 % 영향).

여기 내 jsfiddle이 있습니다. 한 번에 하나의 onScroll () 이벤트 만 트리거 할 수있는 on / off (true / false) var를 사용하여이 문제를 해결할 수 있습니다.

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를 호출하고 무한 반복하는 것을 알 수 있으므로 무한 루프 문제가 있습니다. 또는 오히려 사용자의 지속적인 스크롤이 래퍼의 스크롤 호출과 충돌하고 이벤트 충돌이 발생하며 스크롤 막대에서 최종 결과가 점프하지 않습니다.

이것이 다른 누군가를 돕기를 바랍니다!


좋은 설명! 실제로 그것은 무한 루프를하고 있었다
Ahmed Aboud

네. 당신의 지원에 정말 감사합니다! 도움이됩니다.
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;
        }
    });
});

이것은 내가 여기에 제안 된 답변과 관련된 문제를 해결합니다. 그러나 이것은 문제를 약간만 완화 시키며, 스크롤하려는 거리가 충분히 길면 단계적 / 느린 스크롤이 여전히있을 수 있습니다.
Dan Temple

조건부 / 플래그를 사용하면이 솔루션이 제대로 작동하고 브라우저에 JavaScript를 적용하지 않아도 예상되는 동작과 테스트가 일치합니다.
userabuser

3

@HoldOffHunger 및 @bobince 답변을 기반으로하는 자바 스크립트 전용 솔루션

<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 솔루션을 기반으로 jsFiddle 에 대한 데모 AngularJS 지시문을 만들었습니다 .

사용하기 쉬운:

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

AngularJS 개발자를위한


31
"jQuery가 필요하지 않습니다." 예, 전체 프레임 워크입니다. 더 큰.
PitaJ

2

내가 아는 한 HTML 및 CSS로는 불가능합니다.


글쎄, 이것은 실제로 내가 생각한 것입니다. 그러나 누군가가이 작업을 수행하고이 작업을 수행하는 가장 좋은 방법인지 알고
싶습니다

HTML과 CSS의 경우 가장 좋은 방법은 없습니다. 단순히 불가능합니다. 이런 종류의 기능을 사용하려면 javascript와 같은 다른 기술을 사용해야합니다.
Justus Romijn

1
당신이 찾고 시작하는 몇 가지 팁을 줄 수 있습니까?
psoares

2
이것은 질문에 대한 답변을 제공하지 않습니다. 저자에게 비평을하거나 설명을 요청하려면 게시물 아래에 의견을 남겨주십시오.
SSA

2
@ SSA 그것은 질문에 대답합니다. 문제는 "HTML과 CSS에서만 가능합니까?"였습니다. 그 대답은 "아니오"입니다.
punkrockbuddyholly 2012 년

2

바닐라 자바 ​​스크립트 / 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의 답변을 구현하여 모든 각도 / 네이티브 Js 팬에게

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

웹킷 브라우저 또는 모바일 브라우저에서 iscroll.js를 사용하는 경우 다음을 시도 할 수 있습니다.

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

0

이를 달성하기위한 AngularJs 지시어 :이를 사용하려면 css 클래스 double-hscroll을 요소에 추가하십시오. 이를 위해서는 jQuery와 AngularJ가 필요합니다.

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 사용자에게도 알 수 있습니다. 그러나 창문이 있으면 0.1px이면 충분합니다.


-1

스크롤 방향에 문제가 있습니다 : rtl. 플러그인이 올바르게 지원하지 않는 것 같습니다. 여기 바이올린은 다음과 같습니다 바이올린

Chrome에서는 올바르게 작동하지만 다른 모든 인기있는 브라우저에서는 상단 스크롤 막대 방향이 왼쪽으로 유지됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.