tablonun üstünde ve altında yatay kaydırma çubuğu


160

Sayfamda çok büyük bir değer tablevar. Bu yüzden masanın altına yatay bir kaydırma çubuğu koymaya karar verdim. Ama bu kaydırma çubuğunun da masanın üstünde olmasını istiyorum.

Şablonda ne var:

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

Bu yalnızca HTML ve CSS'de yapılabilir mi?


1
stackoverflow.com/questions/2274627/… Bu çözümü faydalı buldum.
VARSHA DAS

Yanıtlar:


235

Bir öğenin üstünde ikinci bir yatay kaydırma çubuğunu simüle etmek için div, yatay kaydırma özelliğine sahip bir kaydırma çubuğuna yetecek kadar yüksek bir "kukla" yerleştirin. Ardından, kaydırma çubuğundan biri hareket ettirildiğinde diğer öğenin senkronize olmasını sağlamak için yapay öğe ve gerçek öğe için "kaydırma" olayının işleyicilerini ekleyin. Sahte öğe, gerçek öğenin üzerinde ikinci bir yatay kaydırma çubuğu gibi görünür.

Canlı bir örnek için bu kemana bakın

İşte kod :

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

gerçekten harika bir cevap! çok teşekkürler! :) bu yüzden örneğinizi kullanmaya çalıştım, ancak üstteki çubuk çalışmıyor ve genişliği artırmaya çalıştığımda kaydırma çubuğu kayboluyor. neden herhangi bir fikir?
psoares

1
İşe aldın mı? JQuery hakkında daha fazla bilgi için, bkz. Api.jquery.com/scrollLeft (Tabii ki, doğrudan ekran işleyicilerini ekleyerek jQuery olmadan yapabilirsiniz.) JS olmayan kullanıcılar için zarif bozulma için, kukla div'ı DOM by JS'ye ekleyebilirsiniz. .
StanleyH

1
evet işe aldım, sadece <head> <script type = "text / javascript" src = "path"> </script> ekledim. Yani her zaman jquery eklemek @ fudgey eklemek bir eklemek zorunda kaldım? Üzgünüm, javascript ve jquery hala bana çince tür
psoares

4
@StanleyH: div, içindeki tablonun genişliğini otomatik olarak alacak şekilde nasıl ayarlanır? manuel olarak div2 genişliğini belirtmek istemiyorum, ancak otomatik olarak içerdiği tablonun genişliğini almak istiyorum.
sqlchild

3
@CodyGuldner: div, içindeki tablonun genişliğini otomatik olarak alacak şekilde nasıl ayarlanır? manuel olarak div2 genişliğini belirtmek istemiyorum, ancak otomatik olarak içerdiği tablonun genişliğini almak istiyorum.
sqlchild

38

jquery.doubleScrollEklentiyi kullanmayı deneyin :

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
Pawel'in harika eklentisinin jQueryUI gerektirmeyen bir sürümü için github.com/avianey/jqDoubleScroll adresine bakın .
fatal_error

1
Link, beni okuyan bozuk linklerin bulunduğu bakımlı bir GitHub'a yönlendiriyor. Gerçek js denemedim.
Paul Gorbas

19

Her şeyden önce, büyük cevap, @StanleyH. Birisi dinamik kaydırma ile çift kaydırma kabının nasıl yapılacağını merak ediyorsa:

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>

gösteri

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


3
$('.div1').width( $('.div1')[0].scrollWidth)İçeriğin gerçek kaydırma genişliğini elde etmek için kullanın , özellikle tablo gibi bir kap kullanmıyorsanız kullanın. @simo Müthiş çaba arkadaşı.
Clain Dsilva

Açıklığa kavuşturmak için, "div2" div içindeki içeriğin genişliğinin orada bulunan sunucu tarafı dinamik içeriği nedeniyle değişken olması için kendi kodumun çalışması için scrollWidth kodunu değiştirmek zorunda kaldım.
AdamJones

15

JQuery olmadan (2017)

JQuery'e ihtiyacınız olmayabileceğinden, @StanleyH yanıtına dayanan çalışan bir Vanilla JS sürümü:

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>


genişliğinizi bilmiyorsanız bu aslında duyarlı / dinamik değil
elad silver

Evet! @StanleyH tarafından verilen orijinal yanıtla aynı uyarılara sahip
rap-2-h

11

İşi sizin için yapacak bir jQuery eklentisi kullanabilirsiniz:

Eklenti sizin için tüm mantığı işleyecektir.


2
Bu eklenti suwala / jquery.doubleScroll eklentisi ile aynı şeyi yapsa da, window.resize üzerindeki genişliği yeniden hesaplama gibi daha fazla seçeneğe sahiptir
Ivan Hušnjak 30:14

1
Ayrıca jquery kullanıcı arayüzüne bağlı değildir.
tribe84

1
Bu eklentiyi tavsiye ederim, suwala / jquery.doubleScroll'ün geliştirilmiş bir sürümü gibi görünüyor ve benim için çalışıyor
Russell England

İlk olarak harika eklenti için teşekkürler! Ancak kaydırma yönü ile ilgili bir sorunum var: rtl. Doğru desteklemiyor gibi görünüyor. Herhangi bir javascripts gurus burada düzeltmek için biliyorsa keman olduğunu: jsfiddle.net/qsn7tupc/3 Chrome'da ama başka bir tarayıcıda çalıştığını unutmayın.
Vlado

10

StanleyH'nin cevabı mükemmeldi, ama talihsiz bir hata vardı: kaydırma çubuğunun gölgeli alanına tıklamak artık tıkladığınız seçime atlamıyor. Bunun yerine, kaydırma çubuğunun konumunda çok küçük ve biraz can sıkıcı bir artış var.

Test edildi: 4 Firefox sürümü (% 100 etkilenen), 4 Chrome sürümü (% 50 etkilenen).

İşte benim jsfiddle . Tek seferde yalnızca bir onScroll () olayının tetiklenmesine izin veren bir açma / kapama (true / false) var seçeneğiyle bu sorunu çözebilirsiniz:

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

Kabul Edilen Cevapla Sorun Davranışı:

Aslında İstenen Davranış:

Peki, bu neden oluyor? Kod üzerinde çalışırsanız, wrapper1 öğesinin wrapper2'nin scrollLeft öğesini çağırdığını ve wrapper2'nin wrapper1'in scrollLeft öğesini çağırdığını ve bunu sonsuz bir şekilde tekrarladığını göreceksiniz, bu nedenle sonsuz bir döngü sorunumuz var. Ya da, daha doğrusu: kullanıcının kaydırmaya devam etmesi, wrapperx'ın kaydırma çağrısıyla çakışır, bir olay çakışması oluşur ve sonuç kaydırma çubuklarında atlama olmaz.

Umarım bu başka birine yardımcı olur!


harika bir açıklama! gerçekten sonsuz bir döngü yapıyordu
Ahmed Aboud

Evet. Desteğiniz için çok teşekkür ederim! Benim için yararlı.
Giang D.MAI

3

Kaydırıcıları bağlamak işe yaradı, ancak yazıldığı şekilde, daha hafif kaydırma çubuğunun parçasına tıklayıp basılı tutarsanız (kaydırma çubuğunu sürüklerken değil) çoğu tarayıcıda kaydırmayı yavaşlatan bir döngü oluşturur.

Bir bayrakla düzelttim:

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

Bu, burada önerilen cevaplarda da yaşadığım bir sorunu çözüyor. Bununla birlikte, bu yalnızca sorunu hafifletir, kaydırmak istediğiniz mesafe bunun için yeterince büyükse yine de kademeli / yavaş kaydırma olabilir.
Dan Tapınağı

Koşullu / işaretleme ile bu çözüm iyi çalışır ve testler tarayıcıya JavaScript uygulanmadan beklediğiniz davranışla eşleşir.
userabuser

3

@HoldOffHunger ve @bobince yanıtlarına dayanan yalnızca javascript çözümü

<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 çözümüne dayanan Bir oluşturulan angularjs yönergesi üzerinde demo jsFiddle .

Kullanımı kolay:

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

AngularJS geliştiricileri için


32
"JQuery gerekmez." Evet, sadece bütün bir çerçeve. Biggie yok.
PitaJ

2

Bildiğim kadarıyla bu HTML ve CSS ile mümkün değil.


Peki bu aslında düşündüğüm şey .. Ama herkes bunu ve bunu yapmak için en iyi yolu yaptığını bilmek istiyorum ..
psoares

HTML ve CSS için en iyi yol yoktur. Bu mümkün değil. Bu tür bir işlevsellik elde etmek için javascript gibi diğer teknikleri kullanmanız gerekir.
Justus Romijn

1
aramaya başlamak için bazı ipuçları verebilir misiniz?
psoares

2
Bu soruya bir cevap vermez. Bir yazardan eleştiri veya açıklama istemek için gönderilerinin altına bir yorum bırakın.
SSA

2
@SSA soruyu cevaplıyor. Soru "Bu yalnızca HTML ve CSS'de yapmak mümkün mü?" ve bunun cevabı "hayır" dır.
punkrockbuddyholly

2

Vanilya Javascript / Angular'da bunu şöyle yapabilirsiniz:

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'nin cevabını genişleterek ve gereken minimum değeri bulmaya çalışırken, uyguladığım şey:

JavaScript (aşağıdaki gibi bir yerden bir kez çağrılır $(document).ready()):

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

HTML (genişliklerin kaydırma çubuğu uzunluğunu değiştireceğini unutmayı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>

Bu kadar.


1

@ simo'nun cevabını uygulayarak tüm açısal / nativeJs hayranlarına

HTML (değişiklik yok)

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

CSS (değişiklik yok, genişlik:% 90 tasarımımdır)

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

JS (beğen onload) veya ngAfterViewChecked(hepsi asiçin 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 tarayıcısında veya mobil tarayıcıda iscroll.js kullanıyorsanız şunları deneyebilirsiniz:

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

0

Bunu başarmak için bir AngularJs yönergesi: Bunu kullanmak için, öğenize css sınıfı çift hscroll ekleyin. Bunun için jQuery ve AngularJ'lere ihtiyacınız olacak.

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

İşte VueJS için bir örnek

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>

ALACAĞIZ NOT üzerinde height: 12px.. o da Mac Kullanıcıları fark edilecektir o yüzden 12px yaptı. Ancak pencereli, 0.1px yeterince iyi


-1

Kaydırma yönüyle ilgili bir sorun var: rtl. Eklenti doğru desteklemiyor gibi görünüyor. İşte keman: keman

Chrome'da düzgün çalıştığını, ancak diğer tüm popüler tarayıcılarda üst kaydırma çubuğu yönünün solda kaldığını unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.