My goal is to change the opacity of a DIV when I scroll down. It's important that the transition is smooth!
When the scrollTop of the body is 400, the opacity of the Test-div should be 1.
When the scrollTop of the body is 800, the opacity of the Test-div should be 0.
This is what I currently have, but it doesn't work.
window.addEventListener('scroll', function() {
if (document.body.scrollTop > 400) {
var currScrollPos2 = document.body.scrollTop;
document.getElementById('test').style.opacity = -currScrollPos2 / 400 + 2;
}
}
};
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
width: 100%;
}
#test {
width: 200px;
height: 200px;
background-color: red;
position: fixed;
}
<div id="test"></div>
You are close, but the body.scrollTop property does not work in all browsers.
I took the liberty of cleaning up your markup and code a little bit. You were missing a closing parenthesis at the end of you JavaScript, for example. There were also some superfluous rules in your CSS markup, that I deleted.
var test = document.getElementById('test');
window.addEventListener('scroll', function(e) {
// http://stackoverflow.com/a/28633515/962603
var scroll = window.pageYOffset || document.documentElement.scrollTop ||
document.body.scrollTop || 0;
test.style.opacity = Math.max(0, Math.min(1, -scroll / 400 + 2));
});
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
}
#test {
position: fixed;
width: 200px;
height: 200px;
background-color: red;
}
<div id="test"></div>
I had to replace document.body.scrollTop with window.pageYOffset to make it work.
See: document.body.scrollTop Firefox returns 0.
window.addEventListener('scroll', function() {
var currScrollPos2 = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
if (currScrollPos2 > 400) {
document.getElementById('test').style.opacity = -currScrollPos2 / 400 + 2;
}
}
);
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
width: 100%;
}
#test {
width: 200px;
height: 200px;
background-color: red;
position: fixed;
}
<div id="test"></div>
Just syntax error. Replace '}' by ')' at the end of your JS code.
Btw, I recommend using document.addEventListener instead of window.addEventListener
Here is correct code: https://jsfiddle.net/ye082ae9/
document.addEventListener('scroll', function(e) {
if (document.body.scrollTop > 400) {
var currScrollPos2 = document.body.scrollTop;
document.getElementById('test').style.opacity = -currScrollPos2/400 + 2;
}
});
Your code works fine, there is one little spelling error at the end. Just change }; to );
window.addEventListener('scroll', function() {
if (document.body.scrollTop > 400) {
var currScrollPos2 = document.body.scrollTop;
document.getElementById('test').style.opacity = -currScrollPos2/400 + 2;
}
}
);
Related
I am making a window in the bottom of my HTML page that I would like to be resizeable when the user clicks and drags. This is what I have so far:
var main = document.getElementById("dragWindow")
var dragTop = document.querySelector("#dragWindow .draggerTop")
var dragTopDown = false
dragTop.addEventListener("mousedown", function() {
dragTopDown = true
})
document.body.addEventListener("mouseup", function() {
dragTopDown = false
})
document.body.addEventListener("mousemove", function(e) {
if (dragTopDown == false) {
return
}
var h = (window.innerHeight - e.clientY) + "px"
main.style.top = "calc(100% - " + h + ")"
})
#dragWindow {
background: lightgray;
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: calc(100% - 150px);
}
#dragWindow .draggerTop {
position: absolute;
left: 0;
right: 0;
top: 0;
height: 5px;
background: gray;
cursor: ns-resize;
}
Page content here...
<div id="dragWindow">
<div class="draggerTop"></div>
</div>
In the above example, the dragger doesn't work very well. It is slow and won't move most of the time. Is there something that I am missing? It mainly seems to have trouble moving back upward. Also, when you release the mouse, it still is draggable.
I know that there is the CSS resize property, however, I am trying to make a custom version with js.
Nvm, I figuired it out.
Rather than using document.body for the event listeners, I should have used just document. Like this:
var main = document.getElementById("dragWindow")
var dragTop = document.querySelector("#dragWindow .draggerTop")
var dragTopDown = false
dragTop.addEventListener("mousedown", function() {
dragTopDown = true
})
document.addEventListener("mouseup", function() {
dragTopDown = false
})
document.addEventListener("mousemove", function(e) {
if (dragTopDown == false) {
return
}
var h = (window.innerHeight - e.clientY) + "px"
main.style.top = "calc(100% - " + h + ")"
})
#dragWindow {
background: lightgray;
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: calc(100% - 150px);
}
#dragWindow .draggerTop {
position: absolute;
left: 0;
right: 0;
top: 0;
height: 5px;
background: gray;
cursor: ns-resize;
}
Page content here...
<div id="dragWindow">
<div class="draggerTop"></div>
</div>
I would like to change an img src while scrolling down each 20 pixels, so by 100 pixels down from the top it should have changed 5 times, actual src image should be "falling-05.png" I've done this thanks to other tutorials, but while testing, doesn't seems to work properly. Can someone help me out to figure out why?
HTML
<div class="fixedContainer">
<div class="scrollableContainer">
<img class="character" id="character" src="./images/falling-01.png"/>
</div>
</div>
<div class="anotherContainer"></div>
CSS
.fixedContainer {
position: relative;
width: 100%;
height: 100%;
background-color: red;
overflow-y: scroll;
}
.scrollableContainer {
position: relative;
width: 100%;
height: 1800px;
background: rgb(34,193,195);
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1)
100%);
}
.anotherContainer {
position: relative;
width: 100%;
height: 800px;
background-color: white;
display: ;
}
.character {
position: fixed;
right: 140px;
top: 150px;
}
JAVASCRIPT
var image = document.getElementById("character");
var sources = ["falling-01.png", "falling-02.png", "falling-03.png", "falling-04.png", "falling-05.png", "falling-06.png", "falling-07.png", "falling-08.png", "falling-09.png"];
var i = 0;
var breakpoint = 20; // Change to whatever you like
window.addEventListener("scroll", function() {
var scrollDown = document.body.scrollTop;
if (scrollDown >= breakpoint) {
img.setAttribute(src, sources[i]);
breakpoint += 20; //Change to whatever you like
i++;
}
}
first you have a typo:
var image = document.getElementById("character"); <-- defined as image
img.setAttribute(src, sources[i]); <-- referenced as img
Second, you are look at the body for the scroll position
var scrollDown = document.body.scrollTop;
But in your code the part that is scrollable is not the body
.fixedContainer {
...
overflow-y: scroll;
}
There are a few issues with your syntax:
missing an ending parenthesis
img and image
src instead of 'src'
display: ; in .anotherContainer
If you use window.pageYOffset instead of document.body.scrollTop it should work.
You can use
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset :
(document.documentElement || document.body.parentNode ||
document.body).scrollTop;
as described in Detecting by how much user has scrolled.
In the custom slider i have created, the handle is moving beyond the container. But i want it to stay within the container limits. We could just do it simple by setting margin-left as offset in CSS. But My requirement is when the handle right end detect the container's end the handle should not be allowed to move anymore. Any help is appreciated. Thanks.
Demo Link: https://jsfiddle.net/mohanravi/1pbzdyyd/30/
document.getElementsByClassName('contain')[0].addEventListener("mousedown", downHandle);
function downHandle() {
document.addEventListener("mousemove", moveHandle);
document.addEventListener("mouseup", upHandle);
}
function moveHandle(e) {
var left = e.clientX - document.getElementsByClassName('contain')[0].getBoundingClientRect().left;
var num = document.getElementsByClassName('contain')[0].offsetWidth / 100;
var val = (left / num);
if (val < 0) {
val = 0;
} else if (val > 100) {
val = 100;
}
var pos = document.getElementsByClassName('contain')[0].getBoundingClientRect().width * (val / 100);
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
}
function upHandle() {
document.removeEventListener("mousemove", moveHandle);
document.removeEventListener("mouseup", upHandle);
}
.contain {
height: 4px;
width: 450px;
background: grey;
position: relative;
top: 50px;
left: 40px;
}
.bar {
width: 90px;
height: 12px;
background: transparent;
border: 1px solid red;
position: absolute;
top: calc(50% - 7px);
left: 0px;
cursor: ew-resize;
}
<div class='contain'>
<div class='bar'></div>
</div>
You need to change
this
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
to this
if(pos > 90){
document.getElementsByClassName('bar')[0].style.left = pos - 90 + 'px';
}
else{
document.getElementsByClassName('bar')[0].style.left = 0 + 'px';
}
since width of your bar is 90px I am subtracting 90.
See this updated fiddle
I have just started a new website. It's important for me that the users sees this container, so I want it to scroll with the site.
I have an example for this thing: http://gruen-weiss-mannheim.de/
On this site on the left its a green container who stays with smooth scroll on the site if someone scrolls.
I hope you can help me, because I have already tried something, but in this way the container is always on the top.
Would be great If you could help me find a solution!
try {
window.onscroll = setNavPosition;
}
catch(e) {
document.documentElement.onscroll = setNavPosition;
}
function setNavPosition(){
$('.smooth').stop();
try {
if (document.body.scrollTop > document.documentElement.scrollTop) {
var targetPosition = document.body.scrollTop;
}
else {
var targetPosition = document.documentElement.scrollTop;
}
}
catch(e) {
var targetPosition = document.documentElement.scrollTop;
}
$('.smooth').animate({top: targetPosition}, 600);
}
.smooth {
height: 40px;
background-color: orange;
z-index: 2;
position: absolute;
width: 50px;
top: 50px;
}
.body {
height: 700px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body"></div>
<div class="smooth"></div>
So every time I scroll, the container gets back to the top, not with the space in between...
If what you mean is that after the first scrolling it always stops by the edge of the viewport, it is because of this lines var targetPosition = document.body.scrollTop; and var targetPosition = document.documentElement.scrollTop;. I changed them:
try {
window.onscroll = setNavPosition;
}
catch(e) {
document.documentElement.onscroll = setNavPosition;
}
function setNavPosition(){
$('.smooth').stop();
try {
if (document.body.scrollTop > document.documentElement.scrollTop) {
var targetPosition = document.body.scrollTop + 50;
}
else {
var targetPosition = document.documentElement.scrollTop + 50;
}
}
catch(e) {
var targetPosition = document.documentElement.scrollTop;
}
$('.smooth').animate({top: targetPosition}, 600);
}
.smooth {
height: 40px;
background-color: orange;
z-index: 2;
position: absolute;
width: 50px;
top: 50px;
}
.body {
height: 700px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body"></div>
<div class="smooth"></div>
I created this sidebar which sticks when the bottom of the div reaches it's bottom. However, it seems to flicker when I scroll. Could you help what am I doing wrong?
HTML
<div id="header"></div>
<div id="stickymain">
<div class="side" id="stickyside">
<p>
This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too.
</p>
<p>
This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too. This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too. This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too.11
</p>
</div>
<div class="main"></div>
<div class="main"></div>
<div class="main"></div>
<div class="main"></div>
<div class="main"></div>
</div>
<div id="footer"></div>
<script>
CSS
body {
margin: 0;
padding: 10px;
}
#header {
height: 100px;
margin: 0 0 10px;
background: red;
}
#content {
position: relative;
float: left;
width: 100%;
height: auto;
margin: 0 -110px 0 0;
}
.side {
float: right;
width: 100px;
/* min-height: 500px; */
margin: 0 0 0 10px;
background: linear-gradient(red, yellow);
}
.main {
height: 600px;
margin: 0 110px 10px 0;
background: lightgray;
}
#footer {
clear: both;
height: 100px;
background: orange;
}
JS
jQuery(document).ready(function() {
jQuery.fn.stickyTopBottom = function(){
var options = {
container: jQuery('#stickymain'),
top_offset: 0,
bottom_offset: 0
};
console.log(options);
let jQueryel = jQuery(this)
let container_top = options.container.offset().top
let element_top = jQueryel.offset().top
let viewport_height = jQuery(window).height()
jQuery(window).on('resize', function(){
viewport_height = jQuery(window).height()
});
let current_translate = 0
let last_viewport_top = document.documentElement.scrollTop || document.body.scrollTop
jQuery(window).scroll(function(){
var viewport_top = document.documentElement.scrollTop || document.body.scrollTop
let viewport_bottom = viewport_top + viewport_height
let effective_viewport_top = viewport_top + options.top_offset
let effective_viewport_bottom = viewport_bottom - options.bottom_offset
let element_height = jQueryel.height()
let is_scrolling_up = viewport_top < last_viewport_top
let element_fits_in_viewport = element_height < viewport_height
let new_translation = null
if (is_scrolling_up){
if (effective_viewport_top < container_top)
new_translation = 0
else if (effective_viewport_top < element_top + current_translate)
new_translation = effective_viewport_top - element_top
}else if (element_fits_in_viewport){
if (effective_viewport_top > element_top + current_translate)
new_translation = effective_viewport_top - element_top
}else {
let container_bottom = container_top + options.container.height()
if (effective_viewport_bottom > container_bottom)
new_translation = container_bottom - (element_top + element_height)
else if (effective_viewport_bottom > element_top + element_height + current_translate)
new_translation = effective_viewport_bottom - (element_top + element_height)
}
if (new_translation != null){
current_translate = new_translation;
console.log('i am here at css');
jQueryel.css('transform', ('translate(0, '+current_translate+'px)'));
}
last_viewport_top = viewport_top
});
}
jQuery('#stickyside').stickyTopBottom();
});
Except for the flickering issue when I scroll, everything else is working just the way I want. I'm on Mac using Chrome, Firefox and Safari.
CodePen Demo
Instead of using only javascript to do all the work, you can use css properties to help you.
You can just change the position property of your side bar when reaching a certain point of the viewport:
$(window).scroll(function() {
var sTop = $(this).scrollTop();
var footerTop = $('#footer').offset().top;
var sideHeight = $('.side').height();
var headerHeight = $('#header').height();
if(sTop > headerHeight + (sideHeight/2)) {
$('.side').css({
position:'fixed',
bottom:'10px'
});
} else {
$('.side').css({
position:'absolute',
bottom:'inherit'
});
}
});
See this PEN
I hope this one it's ok! :)