Reputation: 3265
I have built a very simple jsfiddle which takes the vertical scrolling from one container, and uses it to scroll left and right in a second container.
Currently as the height of container A has no correlation to the width of container B, the scrolling will end sooner or later depending on heights, margins and so on if the elements inside each container.
I need some formula to make the scrolling relative between the two elements if this is possible.
JS:
const multiElementScroll = ( elem1, elem2 ) => {
elem1.onscroll = function() {
elem2.scrollLeft = this.scrollTop;
};
}
multiElementScroll( div1, div2 );
Basic HTML:
<div class="scroll-box" id="div1">
<h1>A</h1>
<h2>B</h2>
<h2>C</h2>
<h2>D</h2>
<h2>E</h2>
<h2>F</h2>
<h2>G</h2>
<h2>H</h2>
</div>
<div class="scroll-box scroll-box-h" id="div2">
<h1>1</h1>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
</div>
And SCSS:
.scroll-box {
width: 200px;
height: 200px;
overflow-y: scroll;
border: 1px solid #d99;
&-h {
display: flex;
height: 100px;
width: 1000px;
overflow-x: overlay;
overflow-y: hidden;
h1, h2 {
display: inline;
margin: 0 200px 0 0 !important;
}
}
}
.scroll-box h2 { margin-top: 50px; }
Probably makes more sense in the fiddle.
Is there some formula to pass in the height and width and calculate the scrollLeft px offset? Apologies if this is badly worded.
Upvotes: 0
Views: 467
Reputation: 328
Use the heights and widths removing the full (scrollable) size from the visible one, as the value that you read or set is the lower one (top and left). Calculate the percentage and multiply the width:
const multiElementScroll = ( elem1, elem2 ) => {
elem1.onscroll = function() {
var percent = this.scrollTop / (this.scrollHeight - this.clientHeight);
elem2.scrollLeft = (elem2.scrollWidth - elem2.clientWidth) * percent;
};
}
multiElementScroll( div1, div2 );
The intermediate variable percent
is only added for readability, you can inline it if you prefer so. Use
Upvotes: 1
Reputation: 10201
All you need is calculate percentage of vertical scroll and use that percentage to calculate width scroll:
const multiElementScroll = ( elem1, elem2 ) => {
elem1.onscroll = function() {
const scrollTop = this.scrollTop;
const height = this.scrollHeight - this.offsetHeight;
const width = elem2.scrollWidth - elem2.offsetWidth;
elem2.scrollLeft = (scrollTop * 100 / height) * width / 100;
};
}
multiElementScroll( div1, div2 );
.scroll-box {
width:200px;
height:100px;
overflow-y:scroll;
border:1px solid #d99
}
.scroll-box-h {
display:flex;
height:100px;
width:100%;
overflow-x:overlay;
overflow-y:hidden
}
.scroll-box-h h1,
.scroll-box-h h2 {
display:inline;
margin:0 200px 0 0 !important
}
.scroll-box h2 {
margin-top:50px
}
<div class="scroll-box" id="div1">
<h1>A</h1>
<h2>B</h2>
<h2>C</h2>
<h2>D</h2>
<h2>E</h2>
<h2>F</h2>
<h2>G</h2>
<h2>H</h2>
</div>
<div class="scroll-box scroll-box-h" id="div2">
<h1>1</h1>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
</div>
Upvotes: 1
Reputation: 2861
So you need to calculate and set relative scroll position:
const multiElementScroll = ( elem1, elem2 ) => {
elem1.onscroll = function() {
const m = elem1.scrollHeight - elem1.offsetHeight;
const c = elem1.scrollTop / m;
const m2 = elem2.scrollWidth - elem2.offsetWidth;
elem2.scrollLeft = m2 * c;
};
}
Upvotes: 1