Reputation: 1914
I have 3 different tables that scroll horizontally (one scrolls vertically). How do I bind them all together so if I scroll horizontally on one, they all scroll?
I've read through here (Mozilla docs) but I can't get it to work.
It seems like it should be fairly simple.
<div class="page-wrapper relative">
<div class="table-wrapper-outter">
<div class="table-wrapper">
<div class="header header-wrapper">
<div class="header-inner">
<table id="headerTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
</table>
</div>
</div>
<div id="bodyHolder" class="table-content-outter">
<div class="table-content-inner">
<table id="mainTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
<!-- many rows -->
</table>
</div>
</div>
<div class="header footer-wrapper">
<div class="header-inner">
<table id="footerTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
</table>
</div>
</div>
</div>
</div>
And here is the javascript I tried:
function megaTableInit(tableBodyHolder, mainTable, headerTable, footerTable, tablePullDivs, tableRowHeads) {
var bodyHolder = document.getElementById(tableBodyHolder);
var mTable = document.getElementById(mainTable);
var hTable = document.getElementById(headerTable);
var fTable = document.getElementById(footerTable);
var pullDivs = document.getElementsByClassName(tablePullDivs);
var rowHeads = document.getElementsByClassName(tableRowHeads);
bodyHolder.onmousemove = bodyHolder.onscroll = function() {
pullDivs[0].scrollLeft = this.scrollLeft;
var sl = this.scrollLeft;
if(this.oldSL != sl) {
this.oldSL = sl;
for (i=0; i<pullDivs.length; i++) {
pullDivs[i].scrollLeft = this.scrollLeft;
}
}
}
I don't get any errors. It just doesn't do anything with the over divs. When I run console.log for sl
and this.scrollLeft
I get the pixels as I scroll. But it doesn't set the scroll for the other divs.
Any help would be appreciated.
Upvotes: 3
Views: 9478
Reputation: 4437
Okay, you already picked the answer, but there are some elements to your problem that weren't addressed. I liked the idea of binding a scroll to all boxes, including one that is horizontal. I've created this jQuery plugin that will allow you to bind scroll boxes together, and will even bind cross-plane scrolling. You can check it out here
Now, it's a pretty big plugin but I'll explain what it does.
say you have three divs
<div class="scroll">
Vertical
Vertical
vertical
Vertical
Vertical
vertical
</div>
<div class="scroll">
Vertical
Vertical
vertical
Vertical
Vertical
vertical
Vertical
Vertical
vertical
</div>
<div class="scroll" data-horizontal="true"> horizontal horizontal horizontal horizontal </div>
Two of these are vertical (and different heights) and the last one is vertical.
To bind these together, you simply implement the jQuery extension like so:
$(".scroll").bindScroll();
Not only will the plugin bind the scroll, but it will also adjust to accommodate different heights. So if you scroll to the bottom (or far right) of one div, despite the difference in size, it will go to the bottom or far right of the other divs.
If you have any questions regarding the plugin, let me know.
Upvotes: 0
Reputation: 876
I'm not sure if this is exactly what you want but it does what you described, it scrolls all the others when you scroll 1.
$('.scroller').scroll(function(e){
$('.scroller').scrollLeft(e.target.scrollLeft);
});
http://codepen.io/anon/pen/QbaKNz
EDIT: here is the same example with vanilla JavaScript:
var scrollers = document.getElementsByClassName('scroller');
var scrollerDivs = Array.prototype.filter.call(scrollers, function(testElement) {
return testElement.nodeName === 'DIV';
});
function scrollAll(scrollLeft) {
scrollerDivs.forEach(function(element, index, array) {
element.scrollLeft = scrollLeft;
});
}
scrollerDivs.forEach(function(element, index, array) {
element.addEventListener('scroll', function(e) {
scrollAll(e.target.scrollLeft);
});
});
http://codepen.io/anon/pen/zGpNrm
Upvotes: 5
Reputation: 568
Here's a fairly simple implementation:
<style>
.container { width: 300px; height: 400px; overflow-y: scroll; float: left; margin: 20px; }
</style>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<script>
(function(){
var boxes = document.querySelectorAll('.container');
for(var boxIndex = 0, bl = boxes.length; boxIndex < bl; boxIndex++) {
boxes[boxIndex].onscroll = function(){
for(var boxIndex2 = 0, bl2 = boxes.length; boxIndex2 < bl2; boxIndex2++) {
if(boxes[boxIndex2] !== boxes[boxIndex]) {
boxes[boxIndex2].scrollTop = this.scrollTop;
}
}
};
}
})();
</script>
When the container element is scrolled, it updates the scrollTop value for the remaining elements.
Upvotes: 0