This question already has an answer here:
Why do child divs extend beyond their parent div?
(1 answer)
Closed 6 years ago.
I'm trying to create a custom scroller, and I'm using translate3d to scroll. The only problem is, when you scroll all the way to the bottom, the thumb (scroller) goes too far down. I'm using the accepted formula, but for some reason, it goes past its parent wrapper. Here's the formula:
scrollPosition * scrollBarThumb_height / content_height
What am I doing wrong, and how can I get the thumb to fully stay in its parents view?
JSFiddle
console.clear();
var innerWrapper = document.getElementById('innerWrapper');
var scrollBar = document.getElementById('scrollbar');
var scrollBarThumb = scrollBar.firstElementChild
scrollBarThumb.style.height = (innerWrapper.offsetHeight * innerWrapper.offsetHeight / innerWrapper.scrollHeight) + 'px';
innerWrapper.addEventListener('mousewheel', handleScroll);
innerWrapper.addEventListener('DOMMouseScroll', handleScroll);
innerWrapper.style.transform = 'translate3d(0px, 0px, 0px)';
function handleScroll(e) {
// Prevent parents from scrolling
e.preventDefault();
var direction = (e.detail < 0 || e.wheelDelta > 0) ? 1 : -1; // 1 = scroll down, -1 = scroll
var start = parseInt(innerWrapper.style.transform.split(',')[1], 10);
var scrollPosition = start + direction * 100; // Cannot use `deltaY`, because not all browsers support it.
var scrolledToBottom = innerWrapper.scrollHeight - innerWrapper.parentElement.offsetHeight;
scrollPosition = clamp(scrollPosition, -scrolledToBottom, 0);
innerWrapper.style.transform = 'translate3d(0px, ' + scrollPosition + 'px, 0px)';
scrollBarThumb.style.top = -(scrollPosition * scrollBarThumb.offsetHeight / innerWrapper.parentElement.offsetHeight) + 'px'
}
function clamp(val, min, max) {
if (typeof min !== 'number') min = 0;
if (typeof max !== 'number') max = 1;
return Math.min(Math.max(val, min), max);
}
#outerWrapper {
height: 400px;
overflow: hidden;
display: flex;
}
#content {
background-image: url("http://images.freeimages.com/images/premium/previews/3037/30376024-beautiful-flower-portrait.jpg");
width: 400px;
}
#scrollbar {
height: 100%;
width: 50px;
background-color: orange;
}
#scrollbar_thumb {
background-color: yellow;
border: 2px solid blue;
position: relative;
}
<div id="outerWrapper">
<div id="innerWrapper">
<div id="content">
Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero
sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus
Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus
enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar
justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames
ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque
Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem
lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie
vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum
vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque
Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci
Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla.
Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet
consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum
vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque
Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor
</div>
</div>
<div id="scrollbar">
<div id="scrollbar_thumb"></div>
</div>
</div>
The borders were not calculated properly into the total element's height, thus creating the problem.
Simply add box-sizing: border-box; to solve the issue:
#scrollbar_thumb {
...
box-sizing: border-box;
}
working JSFiddle fork: https://jsfiddle.net/azizn/9nfns6kk/
Related
I'm trying to get a three panel layout (Left/Top-Right/Bottom-Right) using jQuery resizable so that I can have the user move the horizontal and vertical splitter/dividers.
I have got a certain amount of the way (see the code below/linked) - but I can't seem to get close enough.
I've looked at the https://api.jqueryui.com/resizable/ documentation - but this is of no help. I've also looked (and continue to look) at http://layout.jquery-dev.com/demos.cfm - but it's not obvious what js is actually required in these (not a very clever move for documentation!)
Where am I going wrong?
Can it be done with just jquery/jquery-ui or do I need another library?
$(function() {
$("#left-container").resizable({
handles: {
e: "#horizontalHandle"
},
resize: function(e, ui) {
$("#right-container").width(
$("#container").width() -
ui.size.width - 20 -
parseInt($("#right-container").css("margin-left")) -
parseInt($("#right-container").css("margin-right")) -
parseInt($("#right-container").css("padding-left")) -
parseInt($("#right-container").css("padding-right")));
}
});
$("#right-container").resizable({
handles: {
s: "#verticalHandle"
},
resize: function(e, ui) {
$("#right-bottom").height($("#container").height() -
ui.size.height - 10 -
parseInt($("#right-top").css("margin-top")) -
parseInt($("#right-top").css("margin-bottom")) -
parseInt($("#right-top").css("padding-top")) -
parseInt($("#right-top").css("padding-bottom")));
}
});
});
#container,
#left,
#right-container,
#horizontalHandle {
height: calc(100vh - 120px);
}
#container {
width: 100vw;
overflow: hidden;
font-family: Lucida Console, Courier New, system-ui, Trebuchet MS, Tahoma, Arial Narrow, Century Gothic, Verdana, sans-serif;
font-size: 9pt;
line-height: 16px;
margin-bottom: 30px;
}
#left,
#right-container,
#horizontalHandle {
position: absolute;
top: 30px;
}
#left,
#right-container {
padding: 10px;
margin: 0;
color: black;
overflow: auto;
}
#left-container {
position: absolute;
width: 25%;
left: 0;
top: 0;
}
#horizontalHandle {
width: 3px;
background: red;
right: 3px;
z-index: 2;
}
#left {
left: 0;
width: calc(100% - 5px);
padding-right: 0;
background-color: lightgray;
}
#right-container {
right: 1px;
width: 75%;
xmargin-left: 10px;
background-color: #f5f5f5;
white-space: nowrap;
}
#right-top {
background-color: lightgrey;
height: 10%;
white-space: normal;
}
#verticalHandle {
height: 3px;
background: red;
bottom: 3px;
z-index: 2;
}
#right-bottom {
background-color: #f3f0f0;
height: 90%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js" ></script><div>
<div id='container'>
<div id='left-container'>
<div id='horizontalHandle' class='ui-resizable-handle ui-resizable-e'></div>
<div id='left'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.'
+'Consectetur lorem donec massa sapien. Quis imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Fringilla est ullamcorper eget nulla. Sagittis id consectetur purus ut faucibus. Consequat ac felis donec et. Tellus orci ac auctor augue mauris augue neque gravida. Ut pharetra sit amet aliquam. A diam maecenas sed enim ut. Cras pulvinar mattis nunc sed blandit libero. Facilisi nullam vehicula ipsum a. Viverra tellus in hac habitasse.'
+'Neque gravida in fermentum et sollicitudin ac orci phasellus egestas. Tellus at urna condimentum mattis pellentesque id nibh. Lorem donec massa sapien faucibus et molestie ac. Aliquam malesuada bibendum arcu vitae. Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum. Pharetra vel turpis nunc eget. Vitae elementum curabitur vitae nunc. Venenatis lectus magna fringilla urna porttitor rhoncus dolor purus non. Enim ut sem viverra aliquet eget sit amet. Sem nulla pharetra diam sit amet nisl suscipit. Amet massa vitae tortor condimentum lacinia quis vel. Erat pellentesque adipiscing commodo elit at imperdiet. Tortor id aliquet lectus proin nibh nisl condimentum id venenatis. A iaculis at erat pellentesque adipiscing. Porta lorem mollis aliquam ut porttitor leo.'
+'Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Bibendum neque egestas congue quisque. Adipiscing vitae proin sagittis nisl rhoncus mattis. Sem nulla pharetra diam sit amet nisl suscipit adipiscing. Sodales ut eu sem integer. Accumsan lacus vel facilisis volutpat. Adipiscing tristique risus nec feugiat in fermentum posuere urna nec. Malesuada fames ac turpis egestas sed tempus urna et pharetra. Bibendum est ultricies integer quis auctor elit. Sagittis nisl rhoncus mattis rhoncus urna. Amet facilisis magna etiam tempor orci eu.'
+'Fusce ut placerat orci nulla. Suscipit adipiscing bibendum est ultricies integer quis auctor elit sed. Platea dictumst quisque sagittis purus sit amet volutpat. </div>
</div>
<div id='right-container'>
<div id='right-top'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.'
+'Consectetur lorem donec massa sapien. Quis imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Fringilla est ullamcorper eget nulla. Sagittis id consectetur purus ut faucibus. Consequat ac felis donec et. Tellus orci ac auctor augue mauris augue neque gravida. Ut pharetra sit amet aliquam. A diam maecenas sed enim ut. Cras pulvinar mattis nunc sed blandit libero. Facilisi nullam vehicula ipsum a. Viverra tellus in hac habitasse.'
+'Neque gravida in fermentum et sollicitudin ac orci phasellus egestas. Tellus at urna condimentum mattis pellentesque id nibh. Lorem donec massa sapien faucibus et molestie ac. Aliquam malesuada bibendum arcu vitae. Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum. Pharetra vel turpis nunc eget. Vitae elementum curabitur vitae nunc. Venenatis lectus magna fringilla urna porttitor rhoncus dolor purus non. Enim ut sem viverra aliquet eget sit amet. Sem nulla pharetra diam sit amet nisl suscipit. Amet massa vitae tortor condimentum lacinia quis vel. Erat pellentesque adipiscing commodo elit at imperdiet. Tortor id aliquet lectus proin nibh nisl condimentum id venenatis. A iaculis at erat pellentesque adipiscing. Porta lorem mollis aliquam ut porttitor leo.'
+'Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Bibendum neque egestas congue quisque. Adipiscing vitae proin sagittis nisl rhoncus mattis. Sem nulla pharetra diam sit amet nisl suscipit adipiscing. Sodales ut eu sem integer. Accumsan lacus vel facilisis volutpat. Adipiscing tristique risus nec feugiat in fermentum posuere urna nec. Malesuada fames ac turpis egestas sed tempus urna et pharetra. Bibendum est ultricies integer quis auctor elit. Sagittis nisl rhoncus mattis rhoncus urna. Amet facilisis magna etiam tempor orci eu.'
+'Fusce ut placerat orci nulla. Suscipit adipiscing bibendum est ultricies integer quis auctor elit sed. Platea dictumst quisque sagittis purus sit amet volutpat. </div>
<div id='verticalHandle' class='ui-resizable-handle ui-resizable-s'></div>
<div id='right-bottom'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.'
+'Consectetur lorem donec massa sapien. Quis imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Fringilla est ullamcorper eget nulla. Sagittis id consectetur purus ut faucibus. Consequat ac felis donec et. Tellus orci ac auctor augue mauris augue neque gravida. Ut pharetra sit amet aliquam. A diam maecenas sed enim ut. Cras pulvinar mattis nunc sed blandit libero. Facilisi nullam vehicula ipsum a. Viverra tellus in hac habitasse.'
+'Neque gravida in fermentum et sollicitudin ac orci phasellus egestas. Tellus at urna condimentum mattis pellentesque id nibh. Lorem donec massa sapien faucibus et molestie ac. Aliquam malesuada bibendum arcu vitae. Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum. Pharetra vel turpis nunc eget. Vitae elementum curabitur vitae nunc. Venenatis lectus magna fringilla urna porttitor rhoncus dolor purus non. Enim ut sem viverra aliquet eget sit amet. Sem nulla pharetra diam sit amet nisl suscipit. Amet massa vitae tortor condimentum lacinia quis vel. Erat pellentesque adipiscing commodo elit at imperdiet. Tortor id aliquet lectus proin nibh nisl condimentum id venenatis. A iaculis at erat pellentesque adipiscing. Porta lorem mollis aliquam ut porttitor leo.'
+'Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Bibendum neque egestas congue quisque. Adipiscing vitae proin sagittis nisl rhoncus mattis. Sem nulla pharetra diam sit amet nisl suscipit adipiscing. Sodales ut eu sem integer. Accumsan lacus vel facilisis volutpat. Adipiscing tristique risus nec feugiat in fermentum posuere urna nec. Malesuada fames ac turpis egestas sed tempus urna et pharetra. Bibendum est ultricies integer quis auctor elit. Sagittis nisl rhoncus mattis rhoncus urna. Amet facilisis magna etiam tempor orci eu.'
+'Fusce ut placerat orci nulla. Suscipit adipiscing bibendum est ultricies integer quis auctor elit sed. Platea dictumst quisque sagittis purus sit amet volutpat. </div>
</div>
</div>
</div>
(Note, I don't know why the stackoverflow code runner doesn't work - but see https://jsfiddle.net/Abeeee/57ofh1gq/20/ for a running version)
Note:
I need to include content scrollbars where applicable
I need to handle window resize
I need the resize handles to sit to the right/bottom of the scrollbars when they are visible
Would also like to memorize the layout for use next time the screen is refreshed
Surely this should be something out of the box but it seems elusive.
I have 2 paragraphs, I styled them with CSS in a way that they would have vertical scrollbars.
When I wheel up or down on one paragraph box, I want the wheel event to also happen on the other paragraph box.
I've done a lot of research and I've read a lot of questions regarding wheel and scroll events.
Here's my code:
document.onload = function() {
document.getElementById("p1").addEventListener("wheel", function(e) {
var n = new Event("wheel");
n.deltaY = e.deltaY;
p2.dispatchEvent(n);
});
}
p {
width: 200px;
height: 200px;
overflow: auto;
}
<p id="p1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros in cursus turpis massa. Libero id faucibus
nisl tincidunt eget nullam non. Donec et odio pellentesque diam. Consequat ac felis donec et odio pellentesque.
Pellentesque id nibh tortor id aliquet lectus proin. Dolor sed viverra ipsum nunc aliquet bibendum enim
facilisis. Sed vulputate odio ut enim blandit. Erat nam at lectus urna duis convallis convallis. Ipsum dolor sit
amet consectetur adipiscing elit. Mattis molestie a iaculis at erat. Risus sed vulputate odio ut. Neque egestas
congue quisque egestas diam in arcu cursus euismod. Blandit massa enim nec dui. Orci nulla pellentesque
dignissim enim sit.
Aliquam purus sit amet luctus. Mauris in aliquam sem fringilla ut morbi tincidunt augue. Vehicula ipsum a arcu
cursus vitae congue mauris rhoncus. Amet dictum sit amet justo. Semper auctor neque vitae tempus quam
pellentesque nec nam aliquam. Viverra nam libero justo laoreet sit amet. Porta lorem mollis aliquam ut
porttitor. Cursus metus aliquam eleifend mi in nulla. Lorem ipsum dolor sit amet consectetur adipiscing elit
pellentesque. Malesuada fames ac turpis egestas. Pellentesque habitant morbi tristique senectus et. Faucibus et
molestie ac feugiat sed lectus. Eget nunc lobortis mattis aliquam. Laoreet id donec ultrices tincidunt arcu non
sodales neque.</p>
<p id="p2">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros in cursus turpis massa. Libero id faucibus
nisl tincidunt eget nullam non. Donec et odio pellentesque diam. Consequat ac felis donec et odio pellentesque.
Pellentesque id nibh tortor id aliquet lectus proin. Dolor sed viverra ipsum nunc aliquet bibendum enim
facilisis. Sed vulputate odio ut enim blandit. Erat nam at lectus urna duis convallis convallis. Ipsum dolor sit
amet consectetur adipiscing elit. Mattis molestie a iaculis at erat. Risus sed vulputate odio ut. Neque egestas
congue quisque egestas diam in arcu cursus euismod. Blandit massa enim nec dui. Orci nulla pellentesque
dignissim enim sit.
Aliquam purus sit amet luctus. Mauris in aliquam sem fringilla ut morbi tincidunt augue. Vehicula ipsum a arcu
cursus vitae congue mauris rhoncus. Amet dictum sit amet justo. Semper auctor neque vitae tempus quam
pellentesque nec nam aliquam. Viverra nam libero justo laoreet sit amet. Porta lorem mollis aliquam ut
porttitor. Cursus metus aliquam eleifend mi in nulla. Lorem ipsum dolor sit amet consectetur adipiscing elit
pellentesque. Malesuada fames ac turpis egestas. Pellentesque habitant morbi tristique senectus et. Faucibus et
molestie ac feugiat sed lectus. Eget nunc lobortis mattis aliquam. Laoreet id donec ultrices tincidunt arcu non
sodales neque.</p>
The event doesn't dispatch and nothing happens.
Manually dispatching events can trigger the associated event listeners, but I don't believe they can be used in this case to trigger an actual content scroll.
A scroll event is dispatched as a consequence of the content scroll happening. A scroll event does not cause the content scroll, it results from it.
An easier way is to just manually measure and set the scrollTop values of the relevant elements:
<script>
document.onload = function(){
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");
p1.addEventListener("scroll", function(e){
p2.scrollTop = p1.scrollTop;
});
}
</script>
Note you should also use the scroll event, not wheel, because there are other ways of scrolling a content box aside from the mouse wheel i.e. with the keyboard.
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");
p1.addEventListener("scroll", function(e){
p2.scrollTop = p1.scrollTop;
});
div {
display: flex;
flex-grow: 1;
border: 1px solid black;
}
p {
max-height: 100px;
overflow: scroll;
}
<div><div><p id="p1">
Nulla sit amet est. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Nunc sed turpis. Vivamus laoreet.
Sed in libero ut nibh placerat accumsan. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam quis ante. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo.
Praesent blandit laoreet nibh. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Aenean imperdiet. Nulla porta dolor. Vestibulum ullamcorper mauris at ligula.
Nullam accumsan lorem in dui. Etiam sit amet orci eget eros faucibus tincidunt. Nulla consequat massa quis enim. In hac habitasse platea dictumst. Vivamus laoreet.
Donec id justo. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Donec mollis hendrerit risus. Fusce ac felis sit amet ligula pharetra condimentum. Vivamus consectetuer hendrerit lacus.
</p></div><div><p id="p2">
Nulla sit amet est. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Nunc sed turpis. Vivamus laoreet.
Sed in libero ut nibh placerat accumsan. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam quis ante. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo.
Praesent blandit laoreet nibh. Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Aenean imperdiet. Nulla porta dolor. Vestibulum ullamcorper mauris at ligula.
Nullam accumsan lorem in dui. Etiam sit amet orci eget eros faucibus tincidunt. Nulla consequat massa quis enim. In hac habitasse platea dictumst. Vivamus laoreet.
Donec id justo. Donec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Donec mollis hendrerit risus. Fusce ac felis sit amet ligula pharetra condimentum. Vivamus consectetuer hendrerit lacus.
</p></div></div>
I want to scroll to the bottom of an element. I searched for solutions here and i got this
but the scrolltop is getting set to zero on first click and if I click on the element again, it scrolls to bottom. I want to scroll to the bottom on first click. The duplicate suggested to me is wrong.
I am using Javascript. Not jquery,
var element = document.querySelector('.message');
element.scrollTop = element.scrollHeight;
.message {
width: 900px;
height: 450px;
margin-top: 0%;
overflow-y: scroll;
}
I have replicated your question and it's working. When I click the first time in the message area the message scrolls to bottom.
Here is the working example:
document.querySelector('.message').addEventListener('click', () => {
var element = document.querySelector('.message');
element.scrollTop = element.scrollHeight;
})
.message {
width: 900px;
height: 100px;
margin-top: 0%;
overflow-y: scroll;
}
<div class="message">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Consectetur lorem donec massa sapien faucibus. Lorem ipsum dolor sit amet consectetur adipiscing elit duis. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Diam quam nulla porttitor massa id. Semper viverra nam libero justo laoreet. Dui vivamus arcu felis bibendum ut tristique et. Proin sed libero enim sed faucibus. Consectetur libero id faucibus nisl tincidunt. Arcu felis bibendum ut tristique et egestas quis ipsum. Quisque id diam vel quam. Dui sapien eget mi proin sed. Sit amet luctus venenatis lectus magna fringilla.
Velit dignissim sodales ut eu sem. Malesuada fames ac turpis egestas sed. Tellus orci ac auctor augue mauris augue neque gravida. Scelerisque eleifend donec pretium vulputate sapien nec sagittis. Euismod quis viverra nibh cras pulvinar mattis nunc sed. Facilisis mauris sit amet massa vitae tortor condimentum. Feugiat nibh sed pulvinar proin. Feugiat in ante metus dictum at tempor commodo ullamcorper a. Laoreet sit amet cursus sit amet. Diam maecenas sed enim ut sem viverra aliquet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam erat. Sagittis orci a scelerisque purus semper eget duis. In hac habitasse platea dictumst vestibulum rhoncus est pellentesque. Odio tempor orci dapibus ultrices in iaculis. Lacus sed turpis tincidunt id.
Tortor condimentum lacinia quis vel eros donec ac odio tempor. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Luctus accumsan tortor posuere ac. Elementum curabitur vitae nunc sed velit dignissim sodales ut eu. Amet cursus sit amet dictum sit amet justo donec enim. Integer vitae justo eget magna fermentum. Lectus arcu bibendum at varius vel pharetra vel. Diam maecenas ultricies mi eget mauris pharetra et. Id velit ut tortor pretium viverra suspendisse potenti nullam ac. Nullam non nisi est sit amet facilisis magna etiam tempor. Laoreet non curabitur gravida arcu ac tortor. Sed velit dignissim sodales ut eu. Id eu nisl nunc mi ipsum faucibus vitae aliquet nec.
Enim ut sem viverra aliquet. Sit amet cursus sit amet dictum. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus. In hac habitasse platea dictumst quisque sagittis purus. Libero justo laoreet sit amet cursus sit amet dictum. Nisl vel pretium lectus quam id. Tempor orci dapibus ultrices in iaculis nunc. Turpis egestas pretium aenean pharetra. Sit amet commodo nulla facilisi. Eget est lorem ipsum dolor sit amet consectetur. Sagittis vitae et leo duis ut diam quam. Nulla aliquet enim tortor at auctor urna nunc id cursus. Curabitur vitae nunc sed velit dignissim sodales. Sit amet massa vitae tortor condimentum lacinia quis vel. Id nibh tortor id aliquet lectus proin.
Varius quam quisque id diam vel quam elementum. Felis eget velit aliquet sagittis id consectetur purus ut. Mauris a diam maecenas sed enim ut sem viverra aliquet. Arcu dui vivamus arcu felis. Ac turpis egestas sed tempus urna et. Vel pharetra vel turpis nunc eget lorem. Praesent tristique magna sit amet purus. In ornare quam viverra orci sagittis. Potenti nullam ac tortor vitae purus. Donec ac odio tempor orci dapibus ultrices in.
Varius quam quisque id diam vel quam elementum. Felis eget velit aliquet sagittis id consectetur purus ut. Mauris a diam maecenas sed enim ut sem viverra aliquet. Arcu dui vivamus arcu felis. Ac turpis egestas sed tempus urna et. Vel pharetra vel turpis nunc eget lorem. Praesent tristique magna sit amet purus. In ornare quam viverra orci sagittis. Potenti nullam ac tortor vitae purus. Donec ac odio tempor orci dapibus ultrices in.
Varius quam quisque id diam vel quam elementum. Felis eget velit aliquet sagittis id consectetur purus ut. Mauris a diam maecenas sed enim ut sem viverra aliquet. Arcu dui vivamus arcu felis. Ac turpis egestas sed tempus urna et. Vel pharetra vel turpis nunc eget lorem. Praesent tristique magna sit amet purus. In ornare quam viverra orci sagittis. Potenti nullam ac tortor vitae purus. Donec ac odio tempor orci dapibus ultrices in.
</div>
I have an effect that makes the header become un-fixed when a specified div hits the top of the screen, and scroll with the rest of the content.
This works perfectly and i wrapped the "const targetTopPos = targetEl.getBoundingClientRect().top" in a resize event listener. But its calculations are wrong if the page is already scrolled and i have no idea why.
Another issue is that if the page is refreshed scrolled down, the header will be there until you scroll.
Here is the code:
window.onresize = function(event) {
const targetTopPos = targetEl.getBoundingClientRect().top;
console.log(targetTopPos);
};
const headerEl = document.querySelector('header')
const targetEl = document.querySelector('#target')
const targetTopPos = targetEl.getBoundingClientRect().top
let isHeaderFixed = true
document.onscroll = () => {
const targetTopOffset = targetEl.getBoundingClientRect().top
if (isHeaderFixed && targetTopOffset < 100) {
headerEl.style.position = 'absolute'
headerEl.style.top = `${targetTopPos - 100}px`
isHeaderFixed = !isHeaderFixed
}
if (!isHeaderFixed && targetTopOffset >= 100) {
headerEl.style.position = 'fixed'
headerEl.style.top = '0px'
isHeaderFixed = !isHeaderFixed
}
}
body {
padding: 0;
margin: 0;
position: relative;
}
header {
position: fixed;
height: 100px;
width: 100%;
background: lightblue;
}
.content {
line-height: 100px;
}
.target {
width: 100%;
background: red;
}
<header>
Custom header
</header>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam suscipit tellus urna, ut tristique felis lobortis sed. Phasellus maximus at magna mattis vulputate. Pellentesque tempor, urna vitae congue pellentesque, est mauris faucibus nulla, vitae molestie leo purus a leo. Curabitur ut mi ac sem finibus consectetur a blandit massa. Morbi ornare tincidunt ipsum, et accumsan erat fringilla a. Cras egestas, nibh vel condimentum ultrices, nunc ipsum tempus magna, eu ullamcorper tortor magna id lacus. Morbi euismod lacus a ligula rutrum, in aliquet lectus blandit. Nam placerat sollicitudin lectus eu ornare. Etiam placerat diam eget magna blandit rutrum. Nulla et luctus massa. Sed sit amet mauris in magna tincidunt consequat. Proin mattis sit amet arcu a gravida. Nullam tempor urna nec dolor convallis consectetur sit amet a elit. Cras ut odio nec lacus efficitur porta nec sit amet justo.
</div>
<div id="target" class="target">target</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam suscipit tellus urna, ut tristique felis lobortis sed. Phasellus maximus at magna mattis vulputate. Pellentesque tempor, urna vitae congue pellentesque, est mauris faucibus nulla, vitae molestie leo purus a leo. Curabitur ut mi ac sem finibus consectetur a blandit massa. Morbi ornare tincidunt ipsum, et accumsan erat fringilla a. Cras egestas, nibh vel condimentum ultrices, nunc ipsum tempus magna, eu ullamcorper tortor magna id lacus. Morbi euismod lacus a ligula rutrum, in aliquet lectus blandit. Nam placerat sollicitudin lectus eu ornare. Etiam placerat diam eget magna blandit rutrum. Nulla et luctus massa. Sed sit amet mauris in magna tincidunt consequat. Proin mattis sit amet arcu a gravida. Nullam tempor urna nec dolor convallis consectetur sit amet a elit. Cras ut odio nec lacus efficitur porta nec sit amet justo.
</div>
I write the "targetTopPos" to the console so you can see the issue
It's because you redefine targetTopPos as a const in your onresize event.
You only have to asign the new value to targetTopPos
see code below
window.onresize = function(event) {
targetTopPos = targetEl.getBoundingClientRect().top;
console.log(targetTopPos);
};
const headerEl = document.querySelector('header')
const targetEl = document.querySelector('#target')
let targetTopPos = targetEl.getBoundingClientRect().top
let isHeaderFixed = true
document.onscroll = () => {
const targetTopOffset = targetEl.getBoundingClientRect().top
if (isHeaderFixed && targetTopOffset < 100) {
headerEl.style.position = 'absolute'
headerEl.style.top = `${targetTopPos - 100}px`
isHeaderFixed = !isHeaderFixed
}
if (!isHeaderFixed && targetTopOffset >= 100) {
headerEl.style.position = 'fixed'
headerEl.style.top = '0px'
isHeaderFixed = !isHeaderFixed
}
}
body {
padding: 0;
margin: 0;
position: relative;
}
header {
position: fixed;
height: 100px;
width: 100%;
background: lightblue;
}
.content {
line-height: 100px;
}
.target {
width: 100%;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
Custom header
</header>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam suscipit tellus urna, ut tristique felis lobortis sed. Phasellus maximus at magna mattis vulputate. Pellentesque tempor, urna vitae congue pellentesque, est mauris faucibus nulla, vitae molestie leo purus a leo. Curabitur ut mi ac sem finibus consectetur a blandit massa. Morbi ornare tincidunt ipsum, et accumsan erat fringilla a. Cras egestas, nibh vel condimentum ultrices, nunc ipsum tempus magna, eu ullamcorper tortor magna id lacus. Morbi euismod lacus a ligula rutrum, in aliquet lectus blandit. Nam placerat sollicitudin lectus eu ornare. Etiam placerat diam eget magna blandit rutrum. Nulla et luctus massa. Sed sit amet mauris in magna tincidunt consequat. Proin mattis sit amet arcu a gravida. Nullam tempor urna nec dolor convallis consectetur sit amet a elit. Cras ut odio nec lacus efficitur porta nec sit amet justo.
</div>
<div id="target" class="target">target</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam suscipit tellus urna, ut tristique felis lobortis sed. Phasellus maximus at magna mattis vulputate. Pellentesque tempor, urna vitae congue pellentesque, est mauris faucibus nulla, vitae molestie leo purus a leo. Curabitur ut mi ac sem finibus consectetur a blandit massa. Morbi ornare tincidunt ipsum, et accumsan erat fringilla a. Cras egestas, nibh vel condimentum ultrices, nunc ipsum tempus magna, eu ullamcorper tortor magna id lacus. Morbi euismod lacus a ligula rutrum, in aliquet lectus blandit. Nam placerat sollicitudin lectus eu ornare. Etiam placerat diam eget magna blandit rutrum. Nulla et luctus massa. Sed sit amet mauris in magna tincidunt consequat. Proin mattis sit amet arcu a gravida. Nullam tempor urna nec dolor convallis consectetur sit amet a elit. Cras ut odio nec lacus efficitur porta nec sit amet justo.
</div>
I'm trying to build a custom scrollbar. I got stuck calculating the correct height for the scrollbar thumb. I did what this comment said to do (and other places I checked said the same formula):
scrollbarArea.offsetHeight * container.offsetHeight / content.scrollHeight
I did the same thing, but the scrollbars thumb is smaller than expected. How can I get the scrollbars thumb to be a regular height based on the height, and scrollHeight?
JSFiddle
console.clear();
var innerWrapper = document.getElementById('innerWrapper');
var scrollBarThumb = document.getElementById('scrollbar_thumb');
scrollBarThumb.style.height = (2 * innerWrapper.scrollHeight / innerWrapper.scrollHeight) + 'px';
console.log(innerWrapper.scrollHeight, innerWrapper.offsetHeight);
#outerWrapper {
height: 500px;
display: flex;
background-color: burlywood;
}
#content {
width: 400px;
}
#scrollbar {
height: 100%;
width: 50px;
background-color: orange;
}
#scrollbar_thumb {
background-color: blue;
}
<div id="outerWrapper">
<div id="innerWrapper">
<div id="content">
Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero
Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae
libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse
vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia
Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla.
Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan
nulla. Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque
accumsan nulla. Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem
lorem neque accumsan nulla. Lacinia Suspendisse vitae libero
</div>
</div>
<div id="scrollbar">
<div id="scrollbar_thumb"></div>
</div>
</div>
To get the formula you have stated you desire:
scrollbarArea.offsetHeight * container.offsetHeight / content.scrollHeight
You could use either
scrollBarThumb.style.height = (Math.pow(innerWrapper.offsetHeight,2)/ innerWrapper.scrollHeight) + 'px';
or
var scrollBarArea = document.getElementById('scrollbar');
scrollBarThumb.style.height = (scrollBarArea.offsetHeight * innerWrapper.offsetHeight / innerWrapper.scrollHeight) + 'px';
Full code:
console.clear();
var innerWrapper = document.getElementById('innerWrapper');
var scrollBarArea = document.getElementById('scrollbar');
var scrollBarThumb = document.getElementById('scrollbar_thumb');
//Target formula:
//scrollbarArea.offsetHeight * container.offsetHeight / content.scrollHeight
//Either
scrollBarThumb.style.height = (scrollBarArea.offsetHeight * innerWrapper.offsetHeight / innerWrapper.scrollHeight) + 'px';
//or
//scrollBarThumb.style.height = (Math.pow(innerWrapper.offsetHeight,2)/ innerWrapper.scrollHeight) + 'px';
console.log(innerWrapper.scrollHeight, innerWrapper.offsetHeight);
#outerWrapper {
height: 500px;
display: flex;
background-color: burlywood;
}
#content {
width: 400px;
}
#scrollbar {
height: 100%;
width: 50px;
background-color: orange;
}
#scrollbar_thumb {
background-color: blue;
}
<div id="outerWrapper">
<div id="innerWrapper">
<div id="content">
Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero
Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae
libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse
vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia
Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla.
Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan
nulla. Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque
accumsan nulla. Lacinia Suspendisse vitae libero Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem
lorem neque accumsan nulla. Lacinia Suspendisse vitae libero
</div>
</div>
<div id="scrollbar">
<div id="scrollbar_thumb"></div>
</div>
</div>