Situation:
I have written a function that detects whether <section> has entered the viewport via scroll, if so .addClass('fadeInUp') else .removeClass('fadeInUp') causing the .animation-element to fade in on the viewport.
Problem: Because the conditional is binded to the scroll function, the 1st <section> that is initially loaded does not .addClass('fadeInUp') until the user scrolls past then scrolls back to the <section>. View JS Fiddle for example
Question: How can I also detect if the initially loaded <section> is in the viewport, then .addClass('fadeInUp'), etc...
Current JS 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() {
$('.animation-element').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInUp')
} else {
$(this).removeClass('fadeInUp')
}
});
});
Here is the JS Fiddle of the prototype.
Simply call the same code you call inside the event hander outside the event handler on the page load.
$(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));
}
function checkElements(selector) {
$(selector).each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInUp')
} else {
$(this).removeClass('fadeInUp')
}
});
}
$(window).scroll(function() {
checkElements('.animation-element'); // <-- check on scroll
});
checkElements('.animation-element'); // <-- check on page load
}
I am not sure what you are asking. Is this what you are looking for?
var updateScroll = function() {
$('.animation-element').each(function() {
...
}
}
$(window).scroll(updateScroll);
updateScroll();
Related
I use this animation effect code with js scroll: https://github.com/daneden/animate.css
My js code include a class in the last line:
$(this).addClass('fadeInLeft');
This great, but sometimes i would like change the fadeInLeft effect (example slideInleft or flipInLeft).
How to add different effect in that line in different div?
This is my js code:
$(document).ready(function() {
// Check if element is scrolled into view
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));
}
// If element is scrolled into view, fade it in
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInLeft');
}
});
});
});
You ca specify the animation type in custom attribute in your element.
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass($(this).data("animationType"));
}
});
});
<div class="scroll-animations">
<div class="animated" data-animation-type="fadeInLeft"></div>
<div class="animated" data-animation-type="flipInLeft"></div>
</div>
I have one page which contains Iframe, iframe has few elements that need to be loaded only if it's in viewport.
But iframe is not scrollable, only master page has scroll. I have written following function but its not working if used with master page.
function isVisible(a) {
var b1 = a.getBoundingClientRect(),
b={},
c = window.innerWidth || doc.documentElement.clientWidth,
d = window.innerHeight || doc.documentElement.clientHeight,
e = function(a, b) {
return document.elementFromPoint(a, b)
};
if(window.frameElement){
var w = window.frameElement.getBoundingClientRect();
// d = window.innerHeight || doc.documentElement.clientHeight;
for( var i in b1){
b[i]=Math.abs(b1[i])+Math.abs(w[i])
}
}else{
b=b1;
}
return !(b.right < 0 || b.bottom < 0 || b.left > c || b.top > d) && (a.contains(e(b.left, b.top)) || a.contains(e(b.right, b.top)) || a.contains(e(b.right, b.bottom)) || a.contains(e(b.left, b.bottom)))
}
Please suggest a way forward, thanks in advance .
This will defer loading of the iframe content until it is scrolled into view.
JSFiddle Example
var $iframe = $("#iframe");
$(window).on("scroll", function() {
// you should probably throttle or debounce this method; I didn't
if (isScrolledIntoView($iframe[0])) {
// assumes same origin for iframe
// if iframe has window object and function "viewportUpdate" call function
var iframeWindow = $iframe[0].contentWindow;
if (iframeWindow && iframeWindow.viewportUpdate)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
iframeWindow.viewportUpdate(docViewTop, docViewBottom);
}
}
});
// from http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling
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));
}
iframe content uses this method to do your magic:
function viewportUpdate(docViewTop, docViewBottom)
{
// do your magic here.. whatever that is
// for example, loop over each "img" element and log to console if in view
$("img").each(function()
{
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
var elementIsInView = (elemBottom <= docViewBottom) && (elemTop >= docViewTop);
if (elementIsInView)
{
console.log("iframe img element is in view");
}
});
}
I have a div that becomes 'fixed' to the bottom of the window once it is scrolled out of view. I only want this behavior when the user is viewing the top half of the page. I do not want a fixed state being applied to the div when the user is on the bottom part of the page.
In short - The issue I have is that a fixed state is being applied when the div is out of view, regardless of page position.
Demo https://jsfiddle.net/DTcHh/19352/
$(window).scroll(function() {
if (isScrolledIntoView($('#myDivWrapper'))) {
if (!initSet) {
initSet = true;
}
$("#myDiv").removeClass('fixed');
} else if (initSet) {
$("#myDiv").addClass('fixed');
}
});
function isScrolledIntoView(elem) {
var $elem = $(elem);
var $window = $(window);
var docViewTop = $window.scrollTop();
var docViewBottom = docViewTop + $window.height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
This method involves editing your markup and your isScrolledIntoView function.
Wrap the top half (or whatever viewable area you want invoked) of your markup in a div give it an id of #top.
Modify your scroll markup as this is currently checking that ALL of the element is in view, you only want a partial check.
Demo https://jsfiddle.net/DTcHh/19366/
$(window).scroll(function() {
if(isScrolledIntoView($('#myDivWrapper'))) {
if (!initSet) {
initSet = true;
}
$("#myDiv").removeClass('fixed');
} else if (initSet && isScrolledIntoView($('#top'))) {
$("#myDiv").addClass('fixed');
}
});
function isScrolledIntoView(elem) {
var $elem = $(elem);
var $window = $(window);
var docViewTop = $window.scrollTop();
var docViewBottom = docViewTop + $window.height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
return ((elemTop <= docViewBottom) && (elemBottom >= docViewTop)) ;
}
I would suggest modifying the isScrolledIntoView function so it accepts a second parameter/ele. This way you'd only need to call it once.
This if block will execute only if you are on lower half of the page
if($(window).scrollTop() + $(window).height()/2 > $(document).height() / 2)
updated fiddle - https://jsfiddle.net/DTcHh/19370/
Sounds like a simple waypoint.js and animate.js issue, but its a bit different. I am using 'isScrolledIntoView' elements, but the problem is that multiple elements are viewable at once on the page. Ideally I would like the first element to show until the next element is entirely viewable so that only one element is present at a time. Right now I am having the issue of more than one element showing at the same time, which makes for a not so nice presentation. Here is what I have tried, and here is the website I have tried it on.
The floating ball shows different elements dependent on the scroll position. I'm sure you will be able to see the issue in this example.
http://www.omnihustle.com
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#home-screen'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip").show("slow");
} else {
$(".coupontooltip").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#services'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip2").show("slow");
} else {
$(".coupontooltip2").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#agents'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip3").show("slow");
} else {
$(".coupontooltip3").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#portal'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip4").show("slow");
} else {
$(".coupontooltip4").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#webdesign'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip5").show("slow");
} else {
$(".coupontooltip5").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#social'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip6").show("slow");
} else {
$(".coupontooltip6").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#pvf'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip7").show("slow");
} else {
$(".coupontooltip7").hide("slow");
}
});
});
</script>
<script>
$(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 >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#pricing'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
$(".coupontooltip8").show("slow");
} else {
$(".coupontooltip8").hide("slow");
}
});
});
</script>
I have some divs, I need to trigger an action (float another div or fire an alert for example) when a certain div is viewed or scrolled to.. What is the best approach to do so?
What you mean by "viewed" I have no idea - but here is how you would do it when the user puts their mouse over the div:
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() {
if(isScrolledIntoView(myelement)) {
// in view
} else {
// not in view
}
});
Credit to Is there a way to detect when an HTML element is hidden from view?
You can probably use the Bullseye jQuery plugin which adds adds enterviewport and leaveviewport events to elements.