I have a little problem with my function scrollIntoView. Indeed, it doesn't work :(
This is my code:
HTML
<section class="page_mission">
<div class="page_mission_text">
<div class="scroll-animations">
<div class="animated fadeInLeft">
<h2>Design <i class="fab fa-css3-alt"></i><i class="fab fa-html5"></i></h2>
<p>Blablabla<br></p>
</div><hr style="width: 75%;">
<div class="animated">
<h2>Modernité <i class="fas fa-dna"></i></h2>
<p>Blablabla</p>
</div><hr style="width: 75%;">
<div class="animated">
<h2>Coûts <i class="far fa-credit-card"></i></h2>
<p>Blablabla</p>
</div>
</div>
</div>
</section>
JS
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInLeft');
}
});
});
Does someone have an idea what's wrong?
Thanks a lot!
It appears to me the fadeInLeft class is being added on scroll as expected. You do, however, need an additional closing curly brace and closing parentheses to close your document ready event handler:
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInLeft');
}
});
});
}); // This was missing
JSFiddle
You also need to make sure to load jQuery before your JavaScript executes. The easiest way is to place something like this in the page's <head> element:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
Related
This is a variation of others topics, the idea is to assign a .js-visible to any element in the DOM, and only when it is visible assign to it a .visible class.
The tricky part is that as all of the elements are using the same class name .js-visible I need to assign the class .visible to only the visible element and ignore all the other DOM elements with the same class name. If it was visible and is not anymore then remove the class name .visible
<style>
.visible {
background: green;
}
</style>
<div class="js-visible" style="height:800px">I am 1st</div>
<div class="js-visible" style="height:800px">I am 2nd</div>
<div class="js-visible" style="height:800px">I am 3rd</div>
<div class="js-visible" style="height:800px">I am 4th</div>
This is not working as desired
$(window).scroll(function() {
var hT = $('.js-visible').offset().top,
hH = $('.js-visible').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
$('.js-visible').addClass('visible')
} else {
$('.js-visible').removeClass('visible')
}
});
Any suggestions?
Based on your code, this function seems to work.
You need to check each element individually.
$(window).scroll(function() {
var wH = $(this).height(),
wS = $(this).scrollTop();
$('.js-visible').each(function() {
var hT = $(this).offset().top,
hH = $(this).outerHeight();
if (wS >= (hT+hH-wH) && (hT >= wS) && (wS+wH >= hT+hH)){
$(this).addClass('visible')
} else {
$(this).removeClass('visible')
}
});
});
.visible {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.visible {
background: green;
}
</style>
<div class="js-visible" style="height:200px">I am 1st</div>
<div class="js-visible" style="height:200px">I am 2nd</div>
<div class="js-visible" style="height:200px">I am 3rd</div>
<div class="js-visible" style="height:200px">I am 4th</div>
I would like to post a demo of the solution for who needs the same solution, you can adapt to your project
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(window).on('resize scroll', function() {
$('.js-visible').each(function() {
var activeColor = $(this).attr('id');
if ($(this).isInViewport()) {
$(this).addClass('visible');
} else {
$(this).removeClass('visible');
}
});
});
.visible {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="js-visible" style="height:800px">I am 1st</div>
<div class="js-visible" style="height:800px">I am 2nd</div>
<div class="" style="height:800px">I am something else</div>
<div class="" style="height:800px">I am something else</div>
<div class="js-visible" style="height:800px">I am 3rd</div>
<div class="js-visible" style="height:800px">I am 4th</div>
I have this code, if scroll down Fade in and show the object
css:
.fadeInBlock {
opacity:0;
}
js:
$(function() {
$(window).scroll( function(){
$('.fadeInBlock').each( function(i){
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* Adjust the "200" to either have a delay or that the content starts fading a bit before you reach it */
bottom_of_window = bottom_of_window + 200;
if( bottom_of_window > bottom_of_object ){
$(this).animate({'opacity':'1'},500);
}
});
});
});
and need solution to fade out the object after scroll up.
Please advise, thank you
Maybe something like this will help
function isVisible(elem){
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
console.log('scroll')
$('.fadeInBlock').each(function(i) {
if (isVisible(this)) {
$(this).animate({
'opacity': '1'
}, 1000);
} else {
$(this).css({
'opacity': '0'
});
}
});
});
https://jsfiddle.net/32feyrhy/4/
$(window).on("load",function() {
$(window).scroll(function() {
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});
.fade {
margin: 50px;
padding: 50px;
background-color: lightgreen;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div>
<div class="fade">Fade In 01</div>
<div class="fade">Fade In 02</div>
<div class="fade">Fade In 03</div>
<div class="fade">Fade In 04</div>
<div class="fade">Fade In 05</div>
<div class="fade">Fade In 06</div>
<div class="fade">Fade In 07</div>
<div class="fade">Fade In 08</div>
<div class="fade">Fade In 09</div>
<div class="fade">Fade In 10</div>
</div>
Please check this link:-Fade In on Scroll Down, Fade Out on Scroll Up - based on element position in window
What I'm trying to accomplish:
Let multiple cards in the queue slide in after each other on document ready and for the elements that arent visible on page load I want the same for them on scroll.
The problem:
All elements slide in at the same time. (Even though I'm using an each loop)
Example:
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
What I did so far:
My markup looks like this:
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
And I want them so slide in after each other by using something like this:
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
I add a class that resets their css to normal, the elements have the transition property
This function is called like this
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
The isScrolledIntoView function is from stackoverflow and looks like this
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
Some thoughts:
Remember that animations on separate elements run in parallel; each element has its own animation queues.
You've said that you had an issue when more elements come into view. That's because you weren't eliminating them from the selection of elements to animate.
Your if (elem.hasClass(animationClass)) check is unnecessary, as you've selected only elements that have that class.
So (see *** commented lines):
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0; // ***
$("." + animationClass).not("." + resetAnimationClass).each(function() { // ***
var elem = $(this);
// *** No `if (elem.hasClass(animationClass))` here, we know it does
if (isScrolledIntoView(elem) == true) {
++counter; // ***
elem.delay(500 * counter).queue(function() { // ***
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
$(document).ready(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0;
$("." + animationClass).not("." + resetAnimationClass).each(function() {
var elem = $(this);
if (isScrolledIntoView(elem) == true) {
++counter;
elem.delay(500 * counter).queue(function() {
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
I've found on here how to do a counter, and I will be using it on a scrolling site.
I'm using the following code:
$(function() {
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 10);
}
}
$("span").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
I've tried to include the following code, but I'm not sure I'm adding it correctly:
if ($('element').visible(true)) {
}
Heres a link to the Jfiddle that is currently working without the if statement. Any help would be appreciated.
http://jsfiddle.net/WpJxn/257/
This is what you should look at: Check if element is visible after scrolling
Here is an example for you that demonstrates this technique: http://jsfiddle.net/XYS2G/ - just try to scroll the Result window.
HTML:
<div class="indicators">
<span class="indicator" data-id="section1">section1</span>
<span class="indicator" data-id="section2">section2</span>
<span class="indicator" data-id="section3">section3</span>
<span class="indicator" data-id="section4">section4</span>
<span class="indicator" data-id="section5">section5</span>
<span class="indicator" data-id="section6">section6</span>
</div>
<div class="sections">
<div class="section" id="section1">section1</div>
<div class="section" id="section2">section2</div>
<div class="section" id="section3">section3</div>
<div class="section" id="section4">section4</div>
<div class="section" id="section5">section5</div>
<div class="section" id="section6">section6</div>
</div>
CSS:
.indicators { position: fixed; }
.section { height: 150px; }
JavaScript:
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
function refreshIndicators() {
$('.indicator').each(function () {
if (isScrolledIntoView($('#' + $(this).attr('data-id')))) {
$(this).css('color', 'red');
} else {
$(this).css('color', 'black');
}
});
}
refreshIndicators();
$(window).bind('scroll', refreshIndicators);
I'm new to Javascript and I cannot figure out what I have to do to change color of the text when an specific element is on screen.
I am using Bootstrap 3.
I want to change color when user hovers in, but I want the color to change according to the element on screen. For instance, if there is a .something element visible on screen, the text would change to color X on hover; if there is a .somethingelse element visible, the text would change to color Y on hover.
Here is the HTML
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<img src="images/black.jpg" alt="Logo">
</div>
<div class="navbar-collapse collapse">
<div class="active" id="navigation-item1">home</div>
<div class="item">about</div>
<div class="item">contact</div>
<div><img class="image1" src="images/image1.png" alt="image1"></div>
<div><img class="image2" src="images/image2.png" alt="image2"></div>
</div>
</div>
</div>
<div class="first-block" id="first-div">some text goes here</div>
<div class="second-block" id="second-div">some more text goes here</div>
Here is the CSS:
.first-block {
background-color:rgba(86, 96, 156, 255)
}
.navbar .container .navbar-collapse > div > a{
float:left;
padding:45px 10px 0px 10px;
color:white;
}
I see you joined just for this, so here's the best answer I can think of:
Instead of assigning an HTML element to the div's color, you need to do something along the lines of: div.style.color = document.getElementById("first-div").style.color;, assigning the color of the div to the other div's color.
Also, you need to attach event listeners to an element so that the scripts actually trigger in the first place:
randomElement.addEventListener("mouseover", changeColorIn);
randomElement.addEventListener("mouseout", changeColorOut);
Where randomElement is a reference to an HTML element (obtained by document.getElementById or such).
Hope I helped!
So, here is the answer (thanks to #azeós):
function isScrolledIntoView(elem){
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
&& (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );}
$(window).scroll(function () {
isOnScreen = isScrolledIntoView("#second-div");
if(isOnScreen){
$(".navbar .navbar-collapse > ul > li > a.item").mouseenter(function() {
$(this).css("color", "#9D45DE")
});
$(".navbar .navbar-collapse > ul > li > a.item").mouseleave(function() {
$(this).css("color", "white")
});
}
});
Thanks to everybody's help.