thanh cuộn ngang trên cùng và dưới cùng của bảng


159

Tôi đã rất lớn tabletrên trang của tôi. Vì vậy, tôi quyết định đặt một thanh cuộn ngang ở dưới cùng của bảng. Nhưng tôi muốn thanh cuộn này cũng ở trên bàn.

Những gì tôi có trong mẫu là đây:

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

Điều này có thể làm chỉ trong HTML và CSS không?


1
stackoverflow.com/questions/2274627/ đá Tôi thấy giải pháp này hữu ích.
VARSHA DAS

Câu trả lời:


234

Để mô phỏng thanh cuộn ngang thứ hai ở trên cùng của một phần tử, đặt "hình nộm" divphía trên phần tử có cuộn ngang, chỉ đủ cao cho thanh cuộn. Sau đó đính kèm các trình xử lý của sự kiện "cuộn" cho phần tử giả và phần tử thực, để có được phần tử khác đồng bộ khi một trong hai thanh cuộn được di chuyển. Phần tử giả sẽ trông giống như một thanh cuộn ngang thứ hai phía trên phần tử thực.

Để biết ví dụ trực tiếp , hãy xem câu đố này

Đây là mã :

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());
  });
});

câu trả lời thực sự tuyệt vời! cảm ơn rất nhiều! :) vì vậy tôi đã cố gắng sử dụng ví dụ của bạn, nhưng thanh trên cùng không hoạt động và khi tôi cố gắng tăng chiều rộng, thanh cuộn sẽ biến mất. bất cứ ý tưởng tại sao?
psoares

1
Bạn đã làm cho nó hoạt động? Để biết thêm về jQuery, hãy xem api.jquery.com/scrollLeft (Tất nhiên, bạn có thể làm điều đó mà không cần jQuery bằng cách đính kèm trực tiếp trình xử lý onscroll.) Để xuống cấp duyên dáng cho người dùng không có JS, bạn có thể thêm div giả vào DOM bằng JS .
StanleyH

1
vâng, tôi đã làm cho nó hoạt động, tôi chỉ thêm <script type = "text / javascript" src = "path"> </ script> vào <head>. Vì vậy, mỗi khi tôi thêm jquery, tôi phải thêm cái mà @fudgey thêm vào? Xin lỗi, javascript và jquery vẫn là loại tiếng Trung đối với tôi
psoares

4
@StanleyH: làm thế nào để thiết lập div để tự động lấy chiều rộng của bảng bên trong nó? Tôi không muốn chỉ định độ rộng của div2 theo cách thủ công, nhưng muốn nó tự động lấy chiều rộng của bảng chứa nó.
sqlchild

3
@CodyGuldner: làm thế nào để thiết lập div tự động lấy chiều rộng của bảng bên trong nó? Tôi không muốn chỉ định độ rộng của div2 theo cách thủ công, nhưng muốn nó tự động lấy chiều rộng của bảng chứa nó.
sqlchild

38

Hãy thử sử dụng jquery.doubleScrollplugin :

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
Xem github.com/avianey/jqDoubleScroll để biết phiên bản plugin tuyệt vời của Pawel không yêu cầu jQueryUI.
fatal_error

1
Liên kết dẫn đến một GitHub không được duy trì với các liên kết bị hỏng khi đọc tôi. Không thử js thực tế.
Paul Gorbas

19

Trước hết, câu trả lời tuyệt vời, @StanleyH. Nếu ai đó đang tự hỏi làm thế nào để tạo hộp cuộn kép với chiều rộng động:

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>

bản giới thiệu

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


3
Sử dụng $('.div1').width( $('.div1')[0].scrollWidth)để có được chiều rộng cuộn thực sự của nội dung, hữu ích khi bạn không sử dụng cụ thể một vùng chứa như bảng. @simo Người bạn đời nỗ lực tuyệt vời.
Clain Dsilva

Để làm rõ, tôi cũng đã phải đổi sang mã thành scrollWidth để mã của riêng tôi hoạt động trong đó độ rộng của nội dung trong div "div2" là do nội dung động phía máy chủ nằm ở đó.
AdamJones

15

Không có JQuery (2017)

Vì bạn có thể không cần JQuery, nên đây là phiên bản Vanilla JS hoạt động dựa trên câu trả lời @StanleyH:

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>


điều này thực sự không đáp ứng / năng động trong trường hợp bạn không biết chiều rộng của mình
bạc

Đúng! nó có cùng cảnh báo với câu trả lời ban đầu của @StanleyH
rap-2-h

11

Bạn có thể sử dụng một plugin jQuery sẽ thực hiện công việc cho bạn:

Plugin sẽ xử lý tất cả logic cho bạn.


2
Mặc dù plugin này thực hiện tương tự như plugin suwala / jquery.doubleScroll nhưng plugin này có nhiều tùy chọn hơn như tính toán lại độ rộng trên window.resize
Ivan Hušnjak

1
Cũng không phụ thuộc vào giao diện người dùng jquery.
lạc84

1
Tôi muốn giới thiệu plugin này, nó trông giống như một phiên bản cải tiến của suwala / jquery.doubleScroll và hoạt động với tôi
Russell England

Đầu tiên cảm ơn bạn cho các plugin tuyệt vời! Tuy nhiên tôi có một vấn đề với hướng cuộn: rtl. Có vẻ như nó không hỗ trợ chính xác. Nếu bất kỳ ai trong số các bạn javascripts gurus biết cách khắc phục thì đây là fiddle: jsfiddle.net/qsn7tupc/3 Lưu ý rằng nó hoạt động trong Chrome nhưng không có trình duyệt nào khác.
Vlado

10

Câu trả lời của StanleyH là tuyệt vời, nhưng nó có một lỗi đáng tiếc: nhấp vào khu vực bóng mờ của thanh cuộn không còn nhảy đến lựa chọn bạn nhấp. Thay vào đó, những gì bạn nhận được là một sự gia tăng rất nhỏ và hơi khó chịu ở vị trí của thanh cuộn.

Đã thử nghiệm: 4 phiên bản Firefox (bị ảnh hưởng 100%), 4 phiên bản Chrome (bị ảnh hưởng 50%).

Đây là jsfiddle của tôi . Bạn có thể khắc phục điều này bằng cách có một biến bật / tắt (đúng / sai) chỉ cho phép một sự kiện onScroll () kích hoạt tại một thời điểm:

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());
});

Hành vi vấn đề với câu trả lời được chấp nhận:

Thực tế hành vi mong muốn:

Vì vậy, tại sao điều này xảy ra? Nếu bạn chạy qua mã, bạn sẽ thấy rằng Wrapper1 gọi scrollLeft của Wrapper2 và Wrapper2 gọi scrollLeft của Wrapper1 và lặp lại điều này vô hạn, vì vậy, chúng ta có một vấn đề vòng lặp vô hạn. Hoặc, đúng hơn: việc cuộn liên tục của người dùng xung đột với lệnh gọi cuộn của Wrapperx, xảy ra xung đột sự kiện và kết quả cuối cùng là không nhảy trong thanh cuộn.

Hy vọng điều này sẽ giúp người khác ra ngoài!


giải thích tuyệt vời! thực sự nó đang thực hiện một vòng lặp vô tận
Ahmed Aboud

Vâng. Cảm ơn bạn rất nhiều vì đã hỗ trợ của bạn! Nó là hữu ích cho tôi.
Giang D.MAI

3

Liên kết các cuộn đã hoạt động, nhưng theo cách viết, nó tạo ra một vòng lặp làm cho việc cuộn chậm trong hầu hết các trình duyệt nếu bạn nhấp vào phần của thanh cuộn nhẹ hơn và giữ nó (không phải khi kéo thanh cuộn).

Tôi đã sửa nó bằng một lá cờ:

$(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;
        }
    });
});

Điều này giải quyết một vấn đề tôi gặp phải với các câu trả lời được đề xuất ở đây. Tuy nhiên, điều này chỉ làm giảm nhẹ vấn đề một chút, vẫn có thể cuộn / chậm cuộn nếu khoảng cách bạn muốn cuộn đủ lớn cho nó.
Đền Đàn

Với điều kiện / cờ, giải pháp này hoạt động tốt và các kiểm tra khớp với hành vi bạn mong đợi mà không cần áp dụng JavaScript trong trình duyệt.
userabuser

3

một giải pháp chỉ dành cho javascript dựa trên câu trả lời của @Hold OfferHunger và @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

Dựa trên giải pháp @StanleyH, tôi đã tạo một lệnh AngularJS , bản demo trên jsFiddle .

Dễ sử dụng:

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

Dành cho nhà phát triển AngularJS


31
"Không cần jQuery." Vâng, chỉ là một khung toàn bộ. Không có vấn đề gì
PitaJ

2

Theo như tôi biết thì điều này là không thể với HTML và CSS.


Vâng, đây thực sự là những gì tôi nghĩ .. Nhưng tôi muốn biết nếu có ai đã làm điều này và cách tốt nhất để làm điều này ..
psoares

Đối với HTML và CSS, không có cách nào tốt nhất. Nó chỉ đơn giản là không thể. Bạn cần sử dụng các kỹ thuật khác, như javascript, để có được loại chức năng này.
Justus Romijn

1
bạn có thể cho một số lời khuyên để bắt đầu tìm kiếm?
psoares

2
Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ.
SSA

2
@SSA nó trả lời câu hỏi. Câu hỏi là "Điều này có thể thực hiện được chỉ trong HTML và CSS không?" và câu trả lời là "không".
punkrockbuddyholly

2

Trong vanilla Javascript / Angular bạn có thể làm như thế này:

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

Mở rộng câu trả lời của StanleyH và cố gắng tìm mức tối thiểu cần thiết, đây là những gì tôi đã thực hiện:

JavaScript (được gọi một lần từ một nơi nào đó như $(document).ready()):

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

HTML (lưu ý rằng độ rộng sẽ thay đổi độ dài thanh cuộn):

<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>

Đó là nó.


1

tới tất cả người hâm mộ góc cạnh / người bản xứ, thực hiện câu trả lời của @ simo

HTML (không thay đổi)

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

CSS (không thay đổi, chiều rộng: 90% là mong muốn của tôi)

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

JS (như onload) hoặc ngAfterViewChecked(tất cả asđều dành cho 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

Nếu bạn đang sử dụng iscroll.js trên trình duyệt webkit hoặc trình duyệt di động, bạn có thể thử:

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

0

Một chỉ thị AngularJs để đạt được điều này: Để sử dụng nó, hãy thêm lớp css double-hscroll vào phần tử của bạn. Bạn sẽ cần jQuery và AngularJs cho việc này.

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

Dưới đây là một ví dụ cho VueJS

trang mục lục

<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>

HÃY LƯU Ý trên height: 12px.. Tôi đã làm cho nó 12px để nó cũng được chú ý trên Người dùng Mac. Nhưng w / windows, 0.1px là đủ tốt


-1

Có một vấn đề với hướng cuộn: rtl. Có vẻ như plugin không hỗ trợ chính xác. Đây là fiddle: fiddle

Lưu ý rằng nó hoạt động chính xác trong Chrome, nhưng trong tất cả các trình duyệt phổ biến khác, hướng thanh cuộn trên cùng vẫn còn lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.