私はとても大きい table
私のページです。そこで、テーブルの下部に水平スクロールバーを配置することにしました。しかし、このスクロールバーもテーブルの一番上に配置したいと思います。
テンプレートにあるのはこれです:
<div style="overflow:auto; width:100%; height:130%">
<table id="data" style="width:100%">...</table>
</div>
これはHTMLとCSSでのみ可能ですか?
私はとても大きい table
私のページです。そこで、テーブルの下部に水平スクロールバーを配置することにしました。しかし、このスクロールバーもテーブルの一番上に配置したいと思います。
テンプレートにあるのはこれです:
<div style="overflow:auto; width:100%; height:130%">
<table id="data" style="width:100%">...</table>
</div>
これはHTMLとCSSでのみ可能ですか?
回答:
要素の上にある2番目の水平スクロールバーをシミュレートするには、水平スクロールがある要素の上に、スクロールバーにdiv
十分な高さの「ダミー」を配置します。次に、ダミー要素と実際の要素の「スクロール」イベントのハンドラーをアタッチして、どちらかのスクロールバーが移動されたときに他の要素を同期させます。ダミー要素は、実際の要素の上にある2番目の水平スクロールバーのように見えます。
ライブの例については、このフィドルを参照してください
これがコードです:
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());
});
});
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>
まず第一に、素晴らしい答え、@ StanleyH。動的な幅のダブルスクロールコンテナーを作成する方法を誰かが疑問に思っている場合:
.wrapper1, .wrapper2 { width: 100%; overflow-x: scroll; overflow-y: hidden; }
.wrapper1 { height: 20px; }
.div1 { height: 20px; }
.div2 { overflow: none; }
$(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());
});
<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>
$('.div1').width( $('.div1')[0].scrollWidth)
コンテンツの実際のスクロール幅を取得するために使用します。テーブルのようなコンテナーを特に使用していない場合に役立ちます。@simo素晴らしい努力仲間。
あなたはJQueryを必要としないかもしれないので、ここに@StanleyH回答に基づいた実用的なバニラ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>
StanleyHの答えは素晴らしかったが、残念なバグが1つありました。スクロールバーの影付きの領域をクリックしても、クリックした選択にジャンプしなくなりました。代わりに、スクロールバーの位置が非常に小さく、やや煩わしい増分になります。
テスト済み:4バージョンのFirefox(100%影響あり)、4バージョンのChrome(50%影響あり)。
これが私のjsfiddleです。これを回避するには、一度に1つのonScroll()イベントのみをトリガーできるon / off(true / false)変数を使用します。
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を呼び出し、これを無限に繰り返すため、無限ループの問題が発生します。または、むしろ:ユーザーの継続的なスクロールがwrapperxのスクロールの呼び出しと競合し、イベントの競合が発生し、最終結果がスクロールバーでジャンプしなくなります。
これが誰かを助けてくれることを願っています!
スクローラーのリンクは機能しましたが、書かれているように、明るいスクロールバーの部分をクリックして押したままにすると(スクローラーをドラッグするときではなく)、ループが作成され、ほとんどのブラウザーでスクロールが遅くなります。
私はそれをフラグで修正しました:
$(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;
}
});
});
@HoldOffHungerと@bobinceの回答に基づくJavaScriptのみのソリューション
<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'));
@StanleyHソリューションに基づいて、私はAngularJSディレクティブ、jsFiddleのデモを作成しました。
使いやすい:
<div data-double-scroll-bar-horizontal> {{content}} or static content </div>
AngularJS開発者向け
私の知る限り、これはHTMLとCSSでは不可能です。
バニラ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;
}
StanleyHの答えを拡張して、必要な最小値を見つけようとすると、以下が実装されたものです。
JavaScript(のような場所から1回呼び出されます$(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>
それでおしまい。
@simoの回答を実装して、すべてのangular / nativeJsファンに
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)
これを実現するための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());
});
});
}
};
});
これが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で十分です