scrollbar horizontal di bagian atas dan bawah tabel

159

Saya sudah sangat besar table . Jadi saya memutuskan untuk meletakkan scrollbar horizontal di bagian bawah tabel. Tetapi saya ingin scrollbar ini juga berada di atas meja.

Apa yang saya miliki di template adalah ini:

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

Apakah ini hanya dapat dilakukan dalam HTML dan CSS?

psoares
sumber
1
stackoverflow.com/questions/2274627/... Saya menemukan solusi ini bermanfaat.
VARSHA DAS

Jawaban:

234

Untuk mensimulasikan scrollbar horizontal kedua di atas elemen, letakkan "dummy" di divatas elemen yang memiliki scrolling horizontal, cukup tinggi untuk scrollbar. Kemudian lampirkan penangan acara "gulir" untuk elemen dummy dan elemen nyata, untuk membuat elemen lainnya selaras ketika salah satu scrollbar dipindahkan. Elemen dummy akan terlihat seperti scrollbar horizontal kedua di atas elemen sebenarnya.

Untuk contoh langsung , lihat biola ini

Ini kodenya :

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());
  });
});
StanleyH
sumber
jawaban yang sangat bagus! Terima kasih banyak! :) jadi saya mencoba menggunakan contoh Anda, tetapi bilah di atas tidak berfungsi, dan ketika saya mencoba menambah lebarnya, bilah gulir menghilang. ada yang tahu kenapa?
psoares
1
Apakah Anda berhasil? Untuk informasi lebih lanjut tentang jQuery, lihat api.jquery.com/scrollLeft (Tentu saja, Anda dapat melakukannya tanpa jQuery dengan memasang penangan onscroll secara langsung.) Untuk degradasi yang anggun untuk pengguna tanpa JS, Anda dapat menambahkan div dummy ke DOM oleh JS .
StanleyH
1
ya saya berhasil, saya hanya menambahkan <script type = "text / javascript" src = "path"> </script> ke <head>. Jadi setiap kali saya menambahkan jquery saya harus menambahkan yang ditambahkan @fudgey? Maaf, javascript dan jquery masih agak Cina bagi saya
psoares
4
@ StanleyH: bagaimana mengatur div untuk secara otomatis mengambil lebar tabel di dalamnya? saya tidak ingin menentukan lebar div2 secara manual, tetapi ingin secara otomatis mengambil lebar tabel yang dikandungnya.
sqlchild
3
@CodyGuldner: bagaimana mengatur div agar secara otomatis mengambil lebar tabel di dalamnya? saya tidak ingin menentukan lebar div2 secara manual, tetapi ingin secara otomatis mengambil lebar tabel yang dikandungnya.
sqlchild
38

Coba gunakan 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>
pawel.suwala
sumber
5
Lihat github.com/avianey/jqDoubleScroll untuk versi plugin mengagumkan Pawel yang tidak memerlukan jQueryUI.
fatal_error
1
Tautan mengarah ke GitHub yang tidak dikelola dengan tautan rusak di baca saya. Belum mencoba js yang sebenarnya.
Paul Gorbas
19

Pertama-tama, jawaban yang bagus, @StanleyH. Jika seseorang bertanya-tanya bagaimana membuat wadah gulir ganda dengan lebar dinamis:

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>

demo

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

simo
sumber
3
Gunakan $('.div1').width( $('.div1')[0].scrollWidth)untuk mendapatkan lebar gulir sebenarnya dari konten, berguna saat Anda tidak secara khusus menggunakan tabel seperti wadah. @simo Teman usaha yang luar biasa.
Clain Dsilva
Untuk memperjelas, saya juga harus mengubah ke kode ke scrollWidth agar kode saya sendiri berfungsi di mana lebar konten dalam div "div2" adalah variabel karena konten dinamis sisi server terletak di sana.
AdamJones
15

Tanpa JQuery (2017)

Karena Anda mungkin tidak memerlukan JQuery, berikut adalah versi Vanilla JS yang berfungsi berdasarkan jawaban @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>

rap-2-h
sumber
ini sebenarnya tidak responsif / dinamis jika Anda tidak tahu lebar Anda
elad silver
Iya! ini memiliki peringatan yang sama dengan jawaban asli oleh @StanleyH
rap-2-h
11

Anda dapat menggunakan plugin jQuery yang akan melakukan pekerjaan untuk Anda:

Plugin akan menangani semua logika untuk Anda.

avianey
sumber
2
Meskipun plugin ini melakukan hal yang sama seperti suwala / jquery.doubleScroll plugin ini memiliki lebih banyak pilihan seperti menghitung ulang lebar di window.resize
Ivan Hušnjak
1
Juga tidak tergantung pada UI jquery.
tribe84
1
Saya akan merekomendasikan plugin ini, sepertinya versi yang lebih baik dari suwala / jquery.doubleScroll dan berfungsi untuk saya
Russell England
Pertama terima kasih atas plugin yang bagus! Namun saya memiliki masalah dengan arah gulir: rtl. Tampaknya tidak mendukungnya dengan benar. Jika ada di antara Anda, javascripts, guru yang tahu cara memperbaikinya di sini adalah biola: jsfiddle.net/qsn7tupc/3 Perhatikan bahwa ia berfungsi di Chrome tetapi tidak ada peramban lain.
Vlado
10

Jawaban StanleyH sangat bagus, tetapi ia memiliki satu bug yang tidak menguntungkan: mengklik area yang diarsir pada scrollbar tidak lagi melompat ke pilihan yang Anda klik. Sebaliknya, yang Anda dapatkan adalah kenaikan yang sangat kecil dan agak menyebalkan di posisi bilah gulir.

Diuji: 4 versi Firefox (100% terpengaruh), 4 versi Chrome (50% terpengaruh).

Ini jsfiddle saya . Anda dapat menyiasatinya dengan memiliki on / off (true / false) var yang memungkinkan hanya satu onScroll () acara untuk memicu sekaligus:

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

Masalah Perilaku Dengan Jawaban yang Diterima:

Perilaku yang Sebenarnya Diinginkan:

Jadi, mengapa ini terjadi?Jika Anda menjalankan kode, Anda akan melihat bahwa wrapper1 memanggil scrollLeft wrapper2, dan wrapper2 memanggil scrollLeft wrapper1, dan ulangi ini tanpa batas, jadi, kami memiliki masalah loop tak terbatas. Atau, lebih tepatnya: pengguliran terus-menerus dari konflik pengguna dengan panggilan wrapperx tentang pengguliran, terjadi suatu peristiwa konflik, dan hasil akhirnya adalah tidak ada lompatan di scrollbar.

Semoga ini bisa membantu orang lain!

HoldOffHunger
sumber
penjelasan yang bagus! memang itu melakukan loop tak terbatas
Ahmed Aboud
Ya. Terima kasih banyak atas dukungannya! Ini sangat membantu saya.
Giang D.MAI
3

Menghubungkan penggulung berfungsi, tetapi dengan cara yang tertulis itu membuat perulangan yang membuat pengguliran lambat di sebagian besar peramban jika Anda mengeklik bagian bilah gulir yang lebih ringan dan menahannya (bukan saat menyeret penggulung).

Saya memperbaikinya dengan bendera:

$(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;
        }
    });
});
Yossi Vainshtein
sumber
Ini memecahkan masalah yang saya alami dengan jawaban yang disarankan di sini juga. Namun, ini hanya sedikit mengurangi masalah, mungkin masih ada step / slow scrolling jika jarak yang ingin Anda gulir cukup besar untuk itu.
Dan Temple
Dengan tanda / bendera solusi ini berfungsi dengan baik dan pengujian sesuai dengan perilaku yang Anda harapkan tanpa JavaScript diterapkan di browser.
userabuser
3

solusi hanya javascript yang didasarkan pada jawaban @HoldOffHunger dan @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'));
Ahmed Aboud
sumber
3

Berdasarkan solusi @StanleyH saya membuat arahan AngularJS , demo di jsFiddle .

Mudah digunakan:

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

Untuk pengembang AngularJS

przno
sumber
31
"Tidak diperlukan jQuery." Ya, hanya kerangka keseluruhan. Bukan masalah besar.
PitaJ
2

Sejauh yang saya tahu ini tidak mungkin dengan HTML dan CSS.

punkrockbuddyholly
sumber
baik ini sebenarnya apa yang saya pikirkan .. Tapi saya ingin tahu jika ada yang melakukan ini dan cara terbaik untuk melakukan ini ..
psoares
Untuk HTML dan CSS, tidak ada cara terbaik. Itu tidak mungkin. Anda perlu menggunakan teknik lain, seperti javascript, untuk mendapatkan fungsi semacam ini.
Justus Romijn
1
dapatkah Anda memberikan beberapa tips untuk mulai mencari?
psoares
2
Ini tidak memberikan jawaban untuk pertanyaan itu. Untuk mengkritik atau meminta klarifikasi dari penulis, tinggalkan komentar di bawah posting mereka.
SSA
2
@ SSSA memang menjawab pertanyaan. Pertanyaannya adalah "Apakah ini mungkin dilakukan hanya dalam HTML dan CSS?" dan jawabannya adalah "tidak".
punkrockbuddyholly
2

Dalam vanilla Javascript / Angular Anda dapat melakukan ini seperti ini:

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;
}
Jakub Bares
sumber
1

Memperluas jawaban StanleyH, dan mencoba menemukan persyaratan minimum, berikut ini yang saya terapkan:

JavaScript (dipanggil sekali dari suatu tempat seperti $(document).ready()):

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

HTML (perhatikan bahwa lebarnya akan mengubah panjang bilah gulir):

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

Itu dia.

MattC
sumber
1

untuk semua penggemar angular / asli, menerapkan jawaban @ simo

HTML (tidak ada perubahan)

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

CSS (tidak ada perubahan, lebar: 90% adalah keinginan saya)

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

JS (suka onload) atau ngAfterViewChecked(semua asuntuk 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)
bresleveloper
sumber
0

Jika Anda menggunakan iscroll.js di browser webkit atau browser seluler, Anda dapat mencoba:

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

Arahan AngularJs untuk mencapai ini: Untuk menggunakannya, tambahkan kelas css double-hscroll ke elemen Anda. Anda akan memerlukan jQuery dan AngularJs untuk ini.

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

  });  

}

  };


});
Tore Aurstad
sumber
0

Ini adalah contoh untuk 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>

MENGAMBIL CATATAN pada height: 12px.. Saya membuatnya 12px sehingga akan diperhatikan pada Pengguna Mac juga. Tapi w / windows, 0.1px cukup baik

Dekan Christian Armada
sumber
-1

Ada masalah dengan arah gulir: rtl. Sepertinya plugin tidak mendukungnya dengan benar. Ini biola: biola

Perhatikan bahwa ia bekerja dengan benar di Chrome, tetapi di semua browser populer lainnya arah bilah gulir atas tetap ada.

Vlado
sumber