แถบเลื่อนแนวนอนที่ด้านบนและด้านล่างของตาราง


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ไว้เหนือองค์ประกอบที่มีการเลื่อนแนวนอนสูงพอสำหรับแถบเลื่อน จากนั้นแนบตัวจัดการของเหตุการณ์ "เลื่อน" สำหรับองค์ประกอบจำลองและองค์ประกอบจริงเพื่อรับองค์ประกอบอื่นในการซิงค์เมื่อเลื่อนแถบเลื่อนอย่างใดอย่างหนึ่ง องค์ประกอบจำลองจะดูเหมือนแถบเลื่อนแนวนอนที่สองเหนือองค์ประกอบจริง

สำหรับตัวอย่างสดดูซอนี้

นี่คือรหัส :

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 คุณสามารถเพิ่ม dummy div เข้าสู่ DOM โดย JS .
StanleyH

1
ใช่ฉันทำให้มันใช้งานได้ฉันเพิ่ม <script type = "text / javascript" src = "path"> </script> ไปยัง <head> เท่านั้น ดังนั้นทุกครั้งที่ฉันเพิ่ม jquery ฉันต้องเพิ่มที่ @fudgey เพิ่มหรือไม่ ขออภัย javascript และ 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
ดูgithub.com/avianey/jqDoubleScrollสำหรับปลั๊กอินสุดยอดของ Pawel ที่ไม่ต้องใช้ jQueryUI
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

เพื่อชี้แจงฉันยังต้องเปลี่ยนรหัสเพื่อ scrollWidth เพื่อให้รหัสของตัวเองทำงานที่ความกว้างของเนื้อหาภายใน "div2" div เป็นตัวแปรเนื่องจากเนื้อหาแบบไดนามิกด้านเซิร์ฟเวอร์อยู่ที่นั่น
AdamJones

15

ไม่มี JQuery (2017)

เนื่องจากคุณอาจไม่ต้องการ JQuery นี่คือเวอร์ชันของ Vanilla JS ที่ทำงานตาม @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>


อันที่จริงแล้วมันไม่ได้ตอบสนอง / แบบไดนามิกในกรณีที่คุณไม่ทราบความกว้างของคุณ
เงิน elad

ใช่! มันมี caveats เช่นเดียวกับคำตอบเดิมโดย @StanleyH
rap-2-h

11

คุณสามารถใช้ปลั๊กอิน jQuery ที่จะทำงานให้คุณ:

ปลั๊กอินจะจัดการกับตรรกะทั้งหมดสำหรับคุณ


2
แม้ว่าปลั๊กอินนี้จะทำสิ่งเดียวกันกับปลั๊กอิน suwala / jquery.doubleScroll แต่ก็มีตัวเลือกเพิ่มเติมเช่นการคำนวณความกว้างบน window.resize
Ivan Hušnjak

1
ยังไม่ขึ้นอยู่กับ jquery UI
tribe84

1
ฉันอยากจะแนะนำปลั๊กอินนี้ดูเหมือนว่ารุ่นปรับปรุงของ suwala / jquery.doubleScroll และทำงานให้ฉัน
รัสเซลอังกฤษ

ก่อนอื่นขอบคุณสำหรับปลั๊กอินที่ยอดเยี่ยม! อย่างไรก็ตามฉันมีปัญหากับทิศทางการเลื่อน: rtl ดูเหมือนว่าไม่รองรับอย่างถูกต้อง หากgavusของคุณในกูรูรู้วิธีแก้ไขที่นี่คือซอ: jsfiddle.net/qsn7tupc/3โปรดทราบว่าใช้งานได้ใน Chrome แต่ไม่มีเบราว์เซอร์อื่น
Vlado

10

คำตอบของ StanleyH นั้นยอดเยี่ยม แต่มีข้อผิดพลาดที่โชคร้ายอย่างหนึ่ง: การคลิกที่พื้นที่แรเงาของแถบเลื่อนจะไม่ข้ามไปยังตัวเลือกที่คุณคลิกอีกต่อไป สิ่งที่คุณจะได้รับคือการเพิ่มขึ้นเล็กน้อยและน่ารำคาญในตำแหน่งของแถบเลื่อน

ทดสอบแล้ว: Firefox 4 เวอร์ชัน (ได้รับผลกระทบ 100%), Chrome 4 เวอร์ชัน (ที่ได้รับผลกระทบ 50%)

นี่คือฉันjsfiddle คุณสามารถแก้ไขได้ด้วยการเปิด / ปิด (จริง / เท็จ) var ที่อนุญาตให้เรียกใช้เหตุการณ์ 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 เรียก scrollLeft ของ wrapper2 และ wrapper2 เรียก scrollLeft ของ wrapper1 และทำซ้ำสิ่งนี้อย่างไม่สิ้นสุดดังนั้นเราจึงมีปัญหาวนวนไม่สิ้นสุด หรือค่อนข้าง: การเลื่อนอย่างต่อเนื่องของความขัดแย้งของผู้ใช้กับการเรียกการเลื่อนของ wrapperx เหตุการณ์ความขัดแย้งเกิดขึ้นและผลลัพธ์สุดท้ายคือการกระโดดในแถบเลื่อน

หวังว่านี่จะช่วยให้คนอื่นออกไป!


คำอธิบายที่ดี! แน่นอนมันกำลังวนรอบไม่สิ้นสุด
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;
        }
    });
});

นี่เป็นการแก้ปัญหาที่ฉันมีพร้อมกับคำตอบที่แนะนำที่นี่เช่นกัน อย่างไรก็ตามสิ่งนี้ช่วยลดปัญหาเพียงเล็กน้อยเท่านั้นยังอาจมีการเลื่อน / การเลื่อนช้าหากระยะทางที่คุณต้องการเลื่อนมีขนาดใหญ่พอสำหรับมัน
วัดแดน

ด้วยเงื่อนไข / ตั้งค่าสถานะโซลูชันนี้ทำงานได้ดีและการทดสอบตรงกับพฤติกรรมที่คุณคาดหวังโดยไม่ต้องใช้ JavaScript ในเบราว์เซอร์
userabuser

3

โซลูชัน javascript เท่านั้นที่ใช้ @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 ฉันได้สร้างคำสั่ง AngularJSสาธิตบนjsFiddle jsFiddle

ง่ายต่อการใช้:

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

สำหรับนักพัฒนา AngularJS


31
"ไม่จำเป็นต้องใช้ jQuery" ใช่เพียงกรอบทั้งหมด ไม่มีปัญหา
PitaJ

2

เท่าที่ฉันทราบนี่เป็นไปไม่ได้กับ HTML และ CSS


นี่คือสิ่งที่ฉันคิด .. แต่ฉันอยากจะรู้ว่าถ้าใครทำสิ่งนี้และวิธีที่ดีที่สุดในการทำเช่นนี้ ..
psoares

สำหรับ HTML และ CSS ไม่มีวิธีที่ดีที่สุด มันเป็นไปไม่ได้. คุณต้องใช้เทคนิคอื่น ๆ เช่นจาวาสคริปต์เพื่อรับฟังก์ชั่นประเภทนี้
Justus Romijn

1
คุณสามารถให้คำแนะนำเพื่อเริ่มมองหาได้ไหม?
psoares

2
สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถาม หากต้องการวิจารณ์หรือขอคำชี้แจงจากผู้แต่งโปรดแสดงความคิดเห็นใต้โพสต์ของพวกเขา
SSA

2
@SSA มันจะตอบคำถาม คำถามคือ "เป็นไปได้ไหมที่จะทำใน HTML และ CSS เท่านั้น" และคำตอบก็คือ "ไม่"
punkrockbuddyholly

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

ถึงแฟน ๆ เชิงมุม / nativeJs ทั้งหมดใช้คำตอบของ @ 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

หากคุณใช้ iscroll.js บนเบราว์เซอร์ webkit หรือเบราว์เซอร์มือถือคุณสามารถลอง:

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

0

คำสั่ง AngularJs เพื่อให้บรรลุสิ่งนี้: หากต้องการใช้ให้เพิ่ม css class 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.1px นั้นดีพอ


-1

มีปัญหาเกี่ยวกับทิศทางการเลื่อน: rtl ดูเหมือนว่าปลั๊กอินไม่รองรับอย่างถูกต้อง นี่คือซอ: ซอ

โปรดทราบว่าทำงานได้อย่างถูกต้องใน Chrome แต่ในเบราว์เซอร์ยอดนิยมอื่น ๆ ทิศทางแถบเลื่อนด้านบนจะยังคงอยู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.