Invoke function only if above particular div - javascript

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/

Related

$(window).scrollTop() Counter

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!

.addClass on initially loaded element

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();

Check if element is in viewport inside iframe

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");
}
});
}

jquery html get visible item data-foo

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));
}

How to trigger an action when a certain div is viewed/scrolled to?

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.

Categories