Javascript fade coloured images and backgrounds - javascript

js and html are not my strong suit but I'm trying to achieve a two simplish effects on the same page.
The user scrolls down the page and the background image/background colour changes as the divs come into view and then leave the screen.
The colors (.panel class) are working great but the image (.fadeimage) is not working at all.
HTML:
<div class="fadeimage">
<h2>image panel</h2>
</div>
<div class="panel" data-color="green">
<h2>Indigo panel</h2>
</div>
<div class="panel" data-color="blue">
<h2>Blue panel</h2>
</div>
<div class="fadeimage">
<h2>image panel</h2>
</div>
<div class="panel" data-color="yellow">
<h2>Yellow panel</h2>
</div>
CSS:
body {
color: #000;
background-color: #f4f4f4;
transition: background-color 1s ease;
}
.panel {
min-height: 100vh;
}
.fadeimage {
opacity: 0;
transition: 0.3s;
background-image: url("/New Page/images/testtakeall.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* colours */
.color-blue {
background-color: #2F8FED;
}
.color-green {
background-color: #4DCF42;
}
.color-yellow {
background-color: #FAEB33;
}
JS: EDITED: This this function breaks while $fadeimage.each(...) is included... it works if I remove it... but obviously this means no image fadein.
$(window).scroll(function() {
// selectors
var $window = $(window),
$body = $('body'),
$panel = $('.panel');
// Change 33% earlier than scroll position so colour is there when you arrive.
var scroll = $window.scrollTop() + ($window.height() / 3);
$fadeimage.each(function () {
var $this = $this;
if ($this.position().top <= scroll && $this.position().top + $this.height() > scroll) {
$this.css('opacity', 1);
}
else {$this.css('opacity', 0)}
})
$panel.each(function () {
var $this = $(this);
// if position is within range of this panel.
// So position of (position of top of div <= scroll position) && (position of bottom of div > scroll position).
// Remember we set the scroll to 33% earlier in scroll var.
if ($this.position().top <= scroll && $this.position().top + $this.height() > scroll) {
// Remove all classes on body with color-
$body.removeClass(function (index, css) {
return (css.match (/(^|\s)color-\S+/g) || []).join(' ');
});
// Add class of currently active div
$body.addClass('color-' + $(this).data('color'));
}
}).scroll();
The opacity of the divs with .fadeimage as a class just stays at 0 the whole time...

You can't use two scroll functions for same document. Instead, try to move everything in one scroll function:
$(window).scroll(function () {
// Add $fadeimage to these variables
var $window = $(window),
$body = $("body"),
$panel = $(".panel"),
$fadeimage = $(".fadeimage");
var scroll = $window.scrollTop() + $window.height() / 3;
$panel.each(function () {
var $this = $(this);
if ( $this.position().top <= scroll && $this.position().top + $this.height() > scroll ) {
$body.removeClass(function (index, css) {
return (css.match(/(^|\s)color-\S+/g) || []).join(" ");
});
$body.addClass("color-" + $(this).data("color"));
}
});
$fadeimage.each(function () {
var $this = $this;
if ( $this.position().top <= scroll && $this.position().top + $this.height() > scroll ) {
$this.css("opacity", 1);
} else {
$this.css("opacity", 0);
}
});
}).scroll();

Related

SlideToggle open only one container at a time Vanilla JS

Maybe someone know how to open only one container at a time? Now in this example you can open all three? I would like to open only one and when it's opened change text to "Close". Any ideas?
Here is the link with a code to codepen: code https://codepen.io/jorgemaiden/pen/YgGZMg
I'll be really apreciate for any help and tips!
You can do it in many ways, but according to your reference, I would just add function that loop through your elements which is not your clicked element, then remove active class if it's present
var linkToggle = document.querySelectorAll(".js-toggle");
for (i = 0; i < linkToggle.length; i++) {
linkToggle[i].addEventListener("click", function(event) {
event.preventDefault();
var container = document.getElementById(this.dataset.container);
this.innerText = "Close";
toggleSlide(container);
});
}
function toggleSlide(container) {
for (i = 0; i < linkToggle.length; i++) {
let el = document.getElementById(linkToggle[i].dataset.container);
if (el != container && el.classList.contains("active")) {
el.style.height = "0px";
linkToggle[i].innerText = "Click";
el.addEventListener(
"transitionend",
function() {
el.classList.remove("active");
}, {
once: true
}
);
}
}
if (!container.classList.contains("active")) {
container.classList.add("active");
container.style.height = "auto";
var height = container.clientHeight + "px";
container.style.height = "0px";
setTimeout(function() {
container.style.height = height;
}, 0);
} else {
container.style.height = "0px";
container.addEventListener(
"transitionend",
function() {
container.classList.remove("active");
}, {
once: true
}
);
}
}
.box {
width: 300px;
border: 1px solid #000;
margin: 10px;
cursor: pointer;
}
.toggle-container {
transition: height 0.35s ease-in-out;
overflow: hidden;
}
.toggle-container:not(.active) {
display: none;
}
<div class="box">
<div class="js-toggle" data-container="toggle-1">Click</div>
<div class="toggle-container" id="toggle-1">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>
<div class="box">
<div class="js-toggle active" data-container="toggle-2">Click</div>
<div class="toggle-container open" id="toggle-2">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>
<div class="box">
<div class="js-toggle" data-container="toggle-3">Click</div>
<div class="toggle-container" id="toggle-3">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>

jquery else condition inside onscroll function

I have a problem in animation in onscroll event.
The if condition works very well when I scroll down and div shows without any problem, but when I scroll up, the else condition does not work, so the div doesn't hide and it is still shown.
This is the code:
$(function () {
'use strict';
var myDiv1 = $('div'),
div1Top = (myDiv1.offset().top) / 2;
$(window).on('scroll', function () {
var docScrollTop = document.documentElement.scrollTop;
if (docScrollTop >= div1Top) {
$('div').animate({opacity: '1'}, 800);
} else {
$('div').css('opacity', '0');
}
});
});
This might not be exactly what you're trying to do, but I think it's in the right ballpark:
<html>
<style>
div {
width: 500px;
height: 500px;
}
.animated_div {
background-color: green;
position: absolute;
top: 2000px;
opacity: 0;
}
.placeholder {
position: absolute;
top:4000px;
}
</style>
<body>
<div class="animated_div"></div> <!--The div that will actually be animated-->
<div class="placeholder"></div> <!--This is just something below the animated DIV, so that you can scroll below the animated DIV -->
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
'use strict';
var myDiv1 = $('.animated_div');
// Start animating the div relative to its middle
var div1Middle = myDiv1.offset().top + myDiv1.height() / 2;
// Keep track of whether the animated_div is displayed or not
var myDiv1Shown = false;
$(window).on('scroll', function () {
var docScrollTop = $(window).scrollTop(); // Top of the window in page coordinates
var docScrollBottom = docScrollTop+$(window).height(); // Bottom of the window in page coordinates
if (div1Middle > docScrollTop && div1Middle < docScrollBottom && !myDiv1Shown) {
// The div middle is within view and it's not already shown, so we need to show it
myDiv1Shown = true;
myDiv1.animate({opacity: '1'}, 800);
} else if ((div1Middle > docScrollBottom || div1Middle < docScrollTop) && myDiv1Shown) {
// The div middle is out of view and it's shown, so we need to hide it
myDiv1Shown = false;
myDiv1.animate({opacity: '0'}, 800);
}
});
});
</script>
</html>
This changes the div opacity to 1 when it's in view and changes it to 0 when it's out of view. It's considered in-view if its vertical middle is in view.
If what you want to do is essentially fade-in the div when the user scrolls it into view and then fade-out the div when the user scrolls it out of view, you might consider this as an alternative:
<html>
<style>
div {
width: 500px;
height: 500px;
}
.animated_div {
background-color: green;
position: absolute;
top: 2000px;
opacity: 0;
}
.placeholder {
position: absolute;
top:4000px;
}
</style>
<body>
<div class="animated_div"></div> <!--The div that will actually be animated-->
<div class="placeholder"></div> <!--This is just something below the animated DIV, so that you can scroll below the animated DIV -->
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
'use strict';
var myDiv1 = $('.animated_div');
var div1Top = myDiv1.offset().top;
var div1Height = myDiv1.height();
var div1Bottom = div1Top + div1Height;
$(window).on('scroll', function () {
var docScrollTop = $(window).scrollTop(); // Top of the window in page coordinates
var docScrollBottom = docScrollTop+$(window).height(); // Bottom of the window in page coordinates
// Calculate fraction of div on page
var topOffPage = Math.max(0, docScrollTop - div1Top);
var bottomOffPage = Math.max(0, div1Bottom - docScrollBottom);
var fractionOnPage = Math.max(0, div1Height - topOffPage - bottomOffPage)/div1Height;
myDiv1.css('opacity', fractionOnPage);
});
});
</script>
</html>
The snippet immediately above sets the opacity of the div to be the fraction of it that is in view (considering only the vertical dimension). So if the entire DIV is on-screen, it's fully opaque. If only half of it is onscreen (with half of it either above the scroll top or below the scroll bottom), then the opacity is 0.5, and so on. If the div is large relative to the screen, then this could cause problems. For instance, if you have a 1000px div, and people are viewing the page with a viewport of height 500px, then the div will only ever be 50% opaque at most. But you can adapt it as necessary to fit your circumstances.

Crossbrowser solution for disable/enable scroll

Long time ago I found somewhere (on stackoverflow I think) code to scroll one window height per scroll. I tried many libraries but that script works just like I want. But it's jumpy when scrolling during animation. So I disable scroll during animation but it works only in Firefox.
I made a fiddle: https://jsfiddle.net/msoys5gc/1/
if( $(window).scrollTop() < $(window).height() * 6 ) {
window.onwheel = function(){ return false; };
}
$('html,body').stop().animate({
scrollTop: divs.eq(div).offset().top
}, 600, function() {
window.onwheel = function(){ return true; };
});
I don`t understand this:
if( $(window).scrollTop() < $(window).height() * 6 )
this will be true until you pass the six slide...
UPDATED: If you want to stop triggering the animation while it is running you can just delete the stop(). Then if you don't want to enqueue animations(and then get strange behaviors), you can just call clearQueue() when the animation has finished.
var divs = $('.section');
var dir = 'up'; // wheel scroll direction
var div = 0; // current div
$(document.body).on('DOMMouseScroll mousewheel', function (e) {
if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
dir = 'down';
}
else {
dir = 'up';
}
// find currently visible div :
div = -1;
divs.each(function(i){
if (div<0 && ($(this).offset().top >= $(window).scrollTop())) {
div = i;
}
});
if (dir == 'up' && div > 0) {
div--;
}
if (dir == 'down' && div < divs.length) {
div++;
}
$('html,body').animate({
scrollTop: divs.eq(div).offset().top
}, 1600, function() {
$('html,body').clearQueue();
});
return false;
});
$(window).resize(function () {
$('html,body').scrollTop(divs.eq(div).offset().top);
});
.section {
height: 100vh;
}
body{
margin: 0px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="section" style="background: yellow;"></div>
<div class="section" style="background: green;"></div>
<div class="section" style="background: blue;"></div>
<div class="section" style="background: red;"></div>
<div class="section" style="background: violet;"></div>
<div class="section" style="background: orange;"></div>
<div class="section" style="background: black;"></div>

Show/hide a div 500 px from top and 500 px before bottom

I have a page where I want an image to appear after scrolling say 500px and I used the "If you want to show a div after scrolling a number of pixels, WITHOUT jquery" code snippet from apaul34208 (show div after 800px scroll). My adapted code is like this:
<!DOCTYPE html>
<html>
<body>
<div id="myID" class="pointer hide">
<img src="image.png">
</div>
<script>
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400) {
myID.className = "pointer show"
} else {
myID.className = "pointer hide"
}
};
window.addEventListener("scroll", myScrollFunc);
</script>
</body>
</html>
and CSS:
.hide {
display: none;
}
.show {
display: block;
margin-top: -80px;
}
Only problem is that I would also like it to DISAPPEAR again lets say 400 px from the bottom of the page. the page-height differs from page to page so I cant just set a range like underneath from say 400-1000 px.
<script>
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400 & y <= 1000 ) {
myID.className = "pointer show"
} else {
myID.className = "pointer hide"
}
};
window.addEventListener("scroll", myScrollFunc);
</script>
</body>
</html>
Anyone have any idea how I can make this happen?
Thanks guys!
$(document).ready(function() {
$(window).scroll(function() {
console.log('scrolling ', $(window).scrollTop(), $(document).height());
if ($(window).scrollTop() >= 400 && $(window).scrollTop() <= ($(document).height() - 600)) {
$('#myID').removeClass('hide');
}
else {
$('#myID').addClass('hide');
}
});
});
.hide {
display: none;
}
.body {
height: 2000px;
}
#myID {
background-color: lightgray;
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body">
<div id="myID" class="pointer hide">
STUFF HERE
</div>
</div>
use document.height to get the height of the document and rest the desired value:
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400 & y <= document.height - 400) {
myID.className = "pointer show";
} else {
myID.className = "pointer hide";
}
};
window.addEventListener("scroll", myScrollFunc);

sticky header change color on top

Im wondering if you can help me here! Im working with a sticky header in JS and CSS. What I want is that when The header is on the top of the page it should be grey --> in scroll down it just disapier --> it appear again on scroll up but in black --> and when it reach the top of the page it becomes grey again... i couldnt make it by self so Im asking for a little help here... this is the whole code:
So far I could do that the header is grey on top --> disapier on scroll down --> appear again on scroll up on black --> BUT COULDNT MAKE THAT IT CHANGE BACK to grey when scroll reach the top of the page.
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function () {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 20);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if (Math.abs(lastScrollTop - st) <= delta) return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down-b');
}
}
if (st > lastScrollTop){
// Scroll Down
$('header').removeClass('nav-down-b').addClass('nav-up');
}
lastScrollTop = st;
}
It works whith 4 css classes:
header {
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
height: 55px;
background-color: #eee;
z-index: 3;
margin-bottom: 42px;
}
.nav-up {
top: -55px;
}
.nav-down {
top:0px; background-color: #eee;
}
.nav-down-b {
top:0px; background-color: #1c1a1b;
}
And the HTML:
<header class="nav-down clearfix">
<div class="container">
<div class="pull-left logo-neg"><img src="/images/PW-emblem-neg.png"></div>
<ul id="user-menu" class="pull-right">
<li><img src="/images/Icon_Nav_Magnify.svg" alt="glass"></li>
<li><img src="/images/Icon_Nav_Cart.svg" alt="cart"> </li>
<li><img src="/images/Icon_Nav_Info.svg" alt="info"> </li>
<li><img src="/images/Icon_Nav_Heart.svg" alt="favorits"> </li>
</ul>
</div>
</header>
Thanks in advance everybody!!
try this code it may help you
$(function () {
// grab the initial top offset of the navigation
var sticky_navigation_offset_top = $('#sticky_navigation').offset().top;
// our function that decides weather the navigation bar should have "fixed" css position or not.
var sticky_navigation = function () {
var scroll_top = $(window).scrollTop(); // our current vertical position from the top
// if we've scrolled more than the navigation, change its position to fixed to stick to top, otherwise change it back to relative
if (scroll_top > sticky_navigation_offset_top) {
$('#sticky_navigation').css({ 'position': 'fixed', 'top': 0, 'left': 0, 'z-index': 10000000, 'background': 'black', 'color':'white', 'width':'100%' });
}
else {
$('#sticky_navigation').css({ 'position': 'relative', 'background':'gray', 'width':'100%' });
}
};
// run our function on load
sticky_navigation();
// and run it again every time you scroll
$(window).scroll(function () {
sticky_navigation();
});
// NOT required:
// for this demo disable all links that point to "#"
$('a[href="#"]').click(function (event) {
event.preventDefault();
});
});
#demo_top_wrapper
{
height:600px;
}
#sticky_navigation
{
background:gray;
height:80px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="demo_top_wrapper">
<div id="sticky_navigation_wrapper">
<div id="sticky_navigation">
this is sticky header
</div>
</div>
</div>
for everybody who needs an effect like i wanted to, id fix it... this is the javascript code working properly:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function () {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 20);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if (Math.abs(lastScrollTop - st) <= delta) return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down-b');
}
}
if (st < delta){
// Scroll Down
$('header').removeClass('nav-down-b').addClass('nav-down');
}
lastScrollTop = st;
}
working with the html and css i writed above. :) Hope you find it usefull!

Categories