I have a div container that is about 70% of the height of the page. The 30% which is outside the div is dim lighted (greyed out).
I am trying to implement a functionality where scrolling down within this container div causes the container div to fill up more of the page (less vertical space is greyed out) and eventually all of it (so 100% height).
Vica versa, when scrolling upward within the container and reaching the top should cause of the greyed out space to become bigger. What is the easiest way to implement this, possibly with the help of a library?
Using the scroll event and a combination of scrollTop, scrollHeight and clientHeight properties, we could get something that resembles your need:
let elem = document.querySelector('div');
elem.addEventListener('scroll', () => {
if(elem.scrollTop == 0) {
elem.style.height = `${elem.clientHeight + 10}px`;
}
if(elem.scrollHeight - elem.clientHeight == elem.scrollTop) {
elem.style.height = `${elem.clientHeight + 1}px`;
}
});
body {
background: #555;
height: 100vh;
margin: 0;
display: flex;
align-items: center;
overflow-y: hidden;
}
div {
background: #ccc;
height: 70%;
width: 100%;
overflow-y: scroll;
}
<body>
<div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</body>
Related
I'm trying to make a fake/duplicated scroll element that is synced with the actual x-scroll of a div in native javaScript. The use case for me is on a long table to have the x-scroll be present on screen when you're not at the bottom of the table.
This solves the situation of having a really wide table with a min-width that exceeds the current page/view-port width, causing the table to side/x-scroll. However, if the table is very long, the scroll can only be set on top or bottom of the table. That means if people are mid-way down the table and want to scroll across to see all of the columns, they would have difficulty in doing it there.
See image:
Yep, it's been done to death IN JQUERY. According to my research, no one on SO knows or has been interested in doing this in native javaScript (esp 2020). My version for reference is also in jQuery, it needs to be converted.
$dupScroll.scroll(function () {
if (scrolling) {
scrolling = false;
return true;
}
scrolling = true;
$tableParent.scrollLeft($dupScroll.scrollLeft());
});
$tableParent.scroll(function () {
if (scrolling) {
scrolling = false;
return true;
}
scrolling = true;
$dupScroll.scrollLeft($tableParent.scrollLeft());
});
All the jQuery solutions:
How to Scroll two div's at the same time?
synchronizing scrolling between 2 divs
synchronizing scrolling between 2 divs with different text size
How to sync the scroll of two divs by ID
synchronise scrolling of two divs
Help is appreciated and will be useful for all the people needing to do the same post-jQuery. I'm currently working on this myself but running into snags here and there, the 1st being attaching a scroll event onto an element. If I make something that works, I'll post it here. Thanks.
Here's the simple way to keep two divs aligned. Javascript doesn't dispatch event on actions from scripts by default, so there's no need to keep track of which div is being scrolled.
const divs = document.querySelectorAll( 'div' );
divs.forEach(div => div.addEventListener( 'scroll', e => {
divs.forEach(d => {
d.scrollTop = div.scrollTop;
d.scrollLeft = div.scrollLeft;
});
}) );
html, body {
height: 100%;
}
body {
display: flex;
padding: 0;
margin: 0;
}
div {
width: 50%;
height: 100%;
overflow: scroll;
}
span {
width: 200vw;
height: 300vh;
display: block;
background: linear-gradient(90deg, transparent, yellow), linear-gradient( 0deg, red, blue, green );
}
#div2 {
margin-top: 30px;
}
<div id="div1"><span></span></div>
<div id="div2"><span></span></div>
With Relative Scroll in Different Sized Containers
If you want to accomplish this with differently sized containers and relative scroll, just normalize the scroll value and multiply it again:
const divs = document.querySelectorAll( 'div' );
divs.forEach(div => div.addEventListener( 'scroll', e => {
const offsetTop = div.scrollTop / (div.scrollHeight - div.clientHeight);
const offsetLeft = div.scrollLeft / (div.scrollWidth - div.clientWidth);
divs.forEach(d => {
d.scrollTop = offsetTop * (d.scrollHeight - d.clientHeight);
d.scrollLeft = offsetLeft * (d.scrollWidth - d.clientWidth);
});
}) );
html, body {
height: 100%;
}
body {
display: flex;
padding: 0;
margin: 0;
}
div {
width: 50%;
height: 100%;
overflow: scroll;
}
span {
width: 200vw;
height: 300vh;
display: block;
background: linear-gradient(90deg, transparent, yellow), linear-gradient( 0deg, red, blue, green );
}
#div2 span {
height: 500vh;
width: 500vw;
}
<div id="div1"><span></span></div>
<div id="div2"><span></span></div>
I have a webpage where there is a full height intro image. Underneath this image is the main body of the site with a regular site header at the top, I'm trying to create an effect where once the user scrolls down to the site header, they cannot scroll back up to view the intro image.
CSS Classes:
Main Intro Image: .cq-fullscreen-intro
Site Header: .nav-down
I had a poke around on StackOverflow but I can't find anything that addresses this circumstance, can anyone point me in the right direction to achieve this using jQuery?
you can use JQuery scrollTop function like this
$(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
// set the height in pixels
if (scroll >= 200) {
// after the scroll is greater than height then you can remove it or hide it
$(".intro-image").hide();
}
});
});
So instead of scrolling, I personally think it would be better to have it be actionable. Forcing the user to manually do the transition (and all in between states) is a bad idea. If the user scrolls half way, and see's something actionable (menu, button, input field) is it usable? If it is, what happens if they submit... very awkward. If it isn't usable, how do they know when it is? How do they know it's because they haven't scrolled all the way. It's very poor user experience.
In the following example, I've created a pseudo-screenport for you to see what's actually going on. The .body container in your real site would be the body element.
Code Pen Example
$(document).ready(function(){
$('.splash-screen').on('click', function(){
$('.splash-screen').addClass("is-hidden");
});
})
html, body{
background: #eee;
margin: 0;
padding: 0;
}
.flex-root {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
}
.web-container {
width: 640px;
height: 480px;
background: #fff;
}
.body {
font-size: 0; // this is only to prevent spacing between img placholders
position: relative;
}
.splash-screen{
position: absolute;
transition: transform 1s ease-in-out;
}
.splash-screen .fa {
position: absolute;
z-index: 1;
font-size: 24px;
color: #fff;
left: 50%;
bottom: 15px;
}
.splash-screen.is-hidden {
transform: translateY(-110%);
transition: transform 1s ease-in-out;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex-root">
<div class="web-container">
<div class="body">
<div class="splash-screen">
<img src="https://via.placeholder.com/640x480?text=Splash+Screen"/>
<i class="fa fa-chevron-circle-up"></i>
</div>
<img src="https://via.placeholder.com/640x60/cbcbcb?text=Menu"/>
<img src="https://via.placeholder.com/640x420/dddddd?text=Site Body"/>
<div>
</div>
</div>
While its not direclty preventing you from scrolling up and its not jQuery, I would suggest to remove/hide the element once its out of view.
You could get the current scroll position, relative to the top of the page, and check if its greater than the elements height:
const target = document.getElementById('my-target')
const targetHeight = target.getBoundingClientRect().height
const scrollEventListener = () => {
if (
document.body.scrollTop > targetHeight ||
document.documentElement.scrollTop > targetHeight
) {
target.remove()
window.removeEventListener('scroll', scrollEventListener)
document.documentElement.scrollTop = 0
}
}
window.addEventListener('scroll', scrollEventListener)
Here is a codepen https://codepen.io/bluebrown/full/aboagov
This question already has answers here:
Detecting when user scrolls to bottom of div with jQuery
(16 answers)
Closed 5 years ago.
I want the alert message to show when the scroll position of the div equals the height of the content inside the div. I have written some jQuery and believe I am very close to being able to do this.
However something is missing. Ignore the scroller div it will be used later. Thanks
$(document).ready(function() {
var box1_height = $("#box1").height();
var scroll_pos = $("#box1").scrollTop();
if (box1_height == scroll_pos) {
alert("It's working");
}
});
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
#background_1 {
background-image: url("http://placehold.it/350x150");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
position: relative;
}
.scroller {
width: 100%;
height: 100vh;
overflow: scroll;
}
.content {
width: 80%;
height: 80vh;
margin: 10vh auto;
background-color: rgba(0, 0, 0, 0.6);
overflow: scroll;
box-size: border-box;
}
<div id="background_1">
<div class="scroller">
<div id="box1" class="content">
content is here
</div>
</div>
</div>
Here's the CodePen Link.
You need to do the following to detect this:
var container = $("#box1") //Fetch the container element once, so we don't squander performance on re-fetches
var box1_height = container.height(); //Get the visible height of the container (not the actual height with scroll)
var scroll_height = container[0].scrollHeight; //Get the content height of the container
var scroll_pos = container.scrollTop(); //Get the top location of the scrollbar in that container
if(scroll_height == box1_height + scroll_pos){ //Check if we're exactly at the bottom
alert("It's working");
}
Explanation:
This is because you know the top value of the scrollbar, but to detect if you're at the bottom of the container, you actually need to know the bottom value of the scrollbar. That is achieved by:
scroll_height == box1_height + scroll_pos
I have an odd situation. Look at this image:
I have that ruler along the top. I don't want it to scroll off when I scroll the content vertically, so I put it outside the scrolling container. But now it doesn't scroll horizontally either. I need to scroll that horizontally in sync with the content container's scrollbar when the content is scrolled.
How can I accomplish this?
This plain javascript function picks up the .scrollLeft value of the #content and reproduces it on the #ruler's .scrollLeft
jsfiddle
document.getElementById("content").addEventListener("scroll", myFunction);
function myFunction() {
var elmnt = document.getElementById("content");
var elmnt2 = document.getElementById("ruler");
elmnt2.scrollLeft = elmnt.scrollLeft;
}
#ruler {
background: skyblue;
overflow: hidden;
width: 100%;
}
#content {
height: 100px;
overflow: scroll;
background: plum;
}
<div id=ruler>1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5</div>
<div id=content>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
</div>
In my project, I need to show a small image in center of the visible part of the container, with respect to the window i.e .loader. Even when the user scrolls the page, the image should be visible in center of .loader.
I successfully implemented this but now I am facing a edgecase which is when user scrolls the page "up to the header" or "down to the footer", the small image is hiding. demo.
This is actually normal behaviour but in these edgecases, I want the image to stick to top/bottom end of the .loader container.
What I want:
Keep the small image always at center of .loader container. (I already implemented this)
when scrolled to any end of .loader container, the image should stick to that end instead of hiding behind the container.
Fiddle
A solution using just css is preferred. I am looking for browser support in IE9+, chrome and firefox.
.header {
height: 600px;
width: 650px;
background-color: grey;
}
.left-side {
height: 300px;
width: 150px;
float: left;
background-color: red;
}
.loader {
background-image: url('http://i.imgur.com/U2njI.jpg');
margin-left: 150px;
height: 1500px;
width: 500px;
background-position: 345px center;
background-repeat: no-repeat;
background-attachment: fixed;
background-color: cornflowerblue;
}
.footer {
height: 600px;
width: 650px;
background-color: silver;
}
<div class="header"></div>
<div class="left-side"></div>
<div class="loader"></div>
<div class="footer"></div>
Here is a working solution with javascript, I hope its behaviour is how you expect it to be. I'm unfortunately not able to test it on IE9 right now but it should work (DEMO):
document.addEventListener('DOMContentLoaded',function() {
var loader = document.querySelector('.loader'),
loaderRect = loader.getBoundingClientRect(),
loaderTop = loaderRect.top + document.body.scrollTop,
loaderBottom = loaderTop + loader.offsetHeight,
initialBgPos = loader.style.backgroundPosition,
imageHeight = 141;
function onScroll() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if(loaderTop >= (scrollTop + (window.innerHeight - imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderTop - scrollTop) + 'px';
} else if(loaderBottom <= (scrollTop + (window.innerHeight + imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderBottom - scrollTop - imageHeight) + 'px';
} else {
loader.style.backgroundPosition = initialBgPos;
}
}
window.addEventListener('scroll', onScroll);
onScroll();
});
To achieve what I think you want. We have to set the position of the .loader div to fixed, then it'll always stay where it's placed, regardless of whether the user scrolls the page, the div will scroll too. In here's how to set the position of loader to fixed in CSS (you may also have to get the position of your fixed div):
.loader{
position: fixed;
left: 100px;
top: 300px;
}
Here's your upadted JSFiddle: http://jsfiddle.net/Ezhb4/4/