I have two functions. The first checks whether an element is within view as the page is scrolled. The second one is meant to calculate the scroll top and if the first function is true, that is when the element is in view, it sets the scrollTop of that element to 0.
My solution to get this done was to start a separate counter that is only activated when the element is in view, but I am having trouble making a working counter. As it is now, the value of i is stuck at 1. Below is my code, any input is appreciated.
var img = $('.banner_img_desktop').find('img');
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() {
var scrollTop = $(window).scrollTop();
var i = 0; // <-- my counter
if (isScrolledIntoView(img)) {
i = i + 1;
var elemScroll = i;
var imgPos = (elemScroll / 8) + 'px';
img.css('transform', 'translateY(' + imgPos + ')');
}
});
As per #GrafiCode Studios's advice! The scope of the variable i was local to the scroll function and I wanted to use it as global! The solution was to declare it outside the scroll function!
Related
I'm trying to track an element every time it enters the viewport in Amplitude. Right now when an element is scrolled into view the jQuery detects the elements id, if it was scrolled up or down, and states that it is a scroll event. These items are display in Amplitude admin. The issue is when the div is in viewport the scroll event is fired for EVERY mouse scroll. So it creates a ton of events when only one is need per element in viewport. How do I fire the event only once but then reset it once its out of viewport again?
function isScrolledIntoView(elem) {
// set offset by 10%
var offSet = jQuery(window).height()*0.1;
// offset scrolltop
var docViewTop = jQuery(window).scrollTop() + offSet;
// set window height area to 80%
var windowSize = jQuery(window).height()*0.8;
var docViewBottom = docViewTop + windowSize;
var elemTop = jQuery(elem).offset().top;
var elemBottom = elemTop + jQuery(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
var lastScrollTop = 0;
jQuery(window).scroll(function (event) {
// detects scroll direction.
var st = jQuery(this).scrollTop();
if (st > lastScrollTop){
var action = 'ScrollDown';
} else {
var action = 'ScrollUp';
}
lastScrollTop = st;
jQuery('.trackScrolling').each(function () {
// get element ID
var elementID = jQuery(this).attr("id");
var ScrollEvents = 'ScrollEvents';
// if in viewport fire event
if (isScrolledIntoView(this) === true) {
gu_event(ScrollEvents, action, elementID);
}
});
});
You'll need to create a boolean flag for each element to check if it is already in the viewport and add another if condition checking for it, something like this:
var elements = [];
var lastScrollTop = 0;
jQuery('.trackScrolling').each(function () {
elements.push({
"elem": this,
"id": jQuery(this).attr("id")),
"inView": false
});
});
function isScrolledIntoView(elem) {
// set offset by 10%
var offSet = jQuery(window).height()*0.1;
// offset scrolltop
var docViewTop = jQuery(window).scrollTop() + offSet;
// set window height area to 80%
var windowSize = jQuery(window).height()*0.8;
var docViewBottom = docViewTop + windowSize;
var elemTop = jQuery(elem).offset().top;
var elemBottom = elemTop + jQuery(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
jQuery(window).scroll(function (event) {
var action;
// detects scroll direction.
var st = jQuery(this).scrollTop();
if (st > lastScrollTop){
action = 'ScrollDown';
} else {
action = 'ScrollUp';
}
lastScrollTop = st;
for (var i = 0; i < elements.length; i++) {
var ScrollEvents = 'ScrollEvents';
if (elements[i].inView === true && isScrolledIntoView(elements[i].elem) === true) {
// do nothing in this case...
console.log('Element ' + elements[i].id + ' is already in view!');
} else if (isScrolledIntoView(elements[i].elem) === true) {
// set the flag in this case and send the event
elements[i].inView = true;
gu_event(ScrollEvents, action, elements[i].id);
} else if (isScrolledIntoView(elements[i].elem) === false) {
// reset the flag in this case
elements[i].inView = false;
}
}
});
Instead of your scroll function continually finding all of the .trackScrolling elements, I've stored a reference to them upfront - the ID of each and whether it's in the viewport are stored in an object.
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();
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/
I have some problem.
I write html code where have about 100 div.
<?php
for ($i=0;$i<100;$i++)
{
$post_block = '
<div id="1_%s" class="simple_wall_post" data-foo="bar_%s">
</div>';
$s = sprintf($post_block,$i,$i);
}
?>
windowsHeight = 10000 px
1 div element height = 100 px
For example facebook autoplay video, if video visible then played, if no stopped.
I can't get current div-foo when visible on window.
how can I implement it? thank you.
Did you try to determine the scrolling of the page, as suggested here: Check if element is visible after scrolling
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 ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
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.