Detecting when div is scrolled to does not work - javascript

I'm having trouble detecting when a certain section of the page is scrolled down to. Once I get down to a certain ID or Class, I'd like to run a couple of functions.
I found this solution here, and tried this below, but the code does not activate:
// Once you scroll into that div ID, this still does not get hit:
$( "#slice_video" ).scroll(function() {
console.log('in scroll...');
});
// In the comments I also saw this solution, tried it but still nothing working:
function isScrolledIntoView(elem) {
// alert("method invoked");
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));
}
if (isScrolledIntoView($('.eco_jumbotron'))){
// initialize modals:
modals.wireModals($());
// Animate in Tiles
animateTiles();
}
JsFiddle for first solution:
http://jsfiddle.net/leongaban/6n4bczmu/
JsFiddle for 2nd solution
http://jsfiddle.net/leongaban/yxkqafwn/

so your issue is you are trying to scroll on the wrong div firstly.. then you are checking the height of the entire window to that div.. so if you changed it to .container scroll event it would alert every time you scroll. what you want to do is check the scroll relative to the div you are scrolling. so something like this.
function isScrolledIntoView( elem, container )
{
var contTop = $(container).offset().top;
var contBottom = contTop + $(container).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= contBottom) && (elemTop >= contTop));
}
$( '.container' ).scroll(function() {
if ( isScrolledIntoView( $( '.box4' ) , $( '.container' ) ) )
{
console.log('HERE!');
}
});
WORKING FIDDLE

You have to listen for the scroll event on the container that has the overflow to scroll or auto.
This code did work:
$('.container' ).scroll(function() {
if($(".box4").position().top < $(".container").position().top + $(".container").height()){
// code
}
});
DEMO
I guess you can do better but it's a start.
I hope it helps.
EDIT:
Don't forget to handle the fact that with this method the event will fire every time you scroll a tiny little bit and the div's position is less than the containers (bottom-edge) position

Related

jQuery based revealer ad is laggy on mobile

Heyo,
I hope you guys can help me out. I tried to build a box that holds an advertisement. The revealer-box (lets call it that) sits in between the content and the ad has a fixed position and sits behind the content (it can't be seen, hidden through z-index and display: none). If the revealer-box is visible on the screen the ad gets a display: block. But the only place where it is visible is at the revealer-box, because all other elements have a higher z-index. Thus the revealer-box works similar to a window where you look through. This was all done and not an issue. The only problem is that it is kinda laggy on mobile (Galaxy S4, Androdid 5.0.1, Chrome). It seems like it has something to do with my jQuery. Let me post it here:
if($(window).width() < 601) {
showElem(".revealer-box");
} else {
hideElem(".revealer-box");
hideElem(".revealer-ad");
}
$(window).resize(function() {
if($(window).width() < 601) {
showElem(".revealer-box");
} else {
hideElem(".revealer-box");
hideElem(".revealer-ad");
}
});
$(window).scroll(function() {
if( isOnScreen(".revealer-box") && $(".revealer-box").hasClass("is-active") ) {
showElem(".revealer-ad");
if(flgCallGA) {
callGA.call($(".revealer-ad"));
flgCallGA = false;
}
} else {
hideElem(".revealer-ad");
}
});
function isOnScreen(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
var elemHeight = $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
function showElem(elem) {
if( !$(elem).hasClass("is-active") ) {
$(elem).addClass("is-active");
}
}
function hideElem(elem) {
if( $(elem).hasClass("is-active") ) {
$(elem).removeClass("is-active");
}
}
As you can see it is only displayed for mobile. And the is-active-class only gives a display: none. nothing more. i hope you can help me.
sincerely,
nunu
As Stan already pointed out, the "scroll" event is fired a few hundred times on a simple scroll. Remove the event listener on scroll and add it again after a short time.
function addListener(){
window.addEventListener("scroll", scrolling);
}
function scrolling(){
//remove the event listener
window.removeEventListener("scroll",scrolling);
window.setTimeout(addListener,500);
}
addListener();

Exclude the "already" visible divs after page load, from being animated

I have the follwing code which animates some divs thru adding an animation class to them when they come into browser window.
My only problem comes with the divs that are "already" visible in the screen after page load, once I do a little scroll they animate.
What is the best way to exclude the divs that are "already" visible in the browser window after page load?
function isElementInViewport(elem) {
var $elem = $(elem);
// Get the scroll position of the page.
var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html');
var viewportTop = $(scrollElem).scrollTop();
var viewportBottom = viewportTop + $(window).height();
// Get the position of the element on the page.
var elemTop = Math.round( $elem.offset().top );
var elemBottom = elemTop + $elem.height();
return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}
function checkAnimation_aec() {
var $elem = $('.aec');
// If the animation has already been started
if ($elem.hasClass('icon_start')) return;
if (isElementInViewport($elem)) {
// Start the animation
$elem.addClass('icon_start');
}
}
// Capture scroll events & run the functions
$(document).ready(function(){
$(window).scroll(function(){
checkAnimation_aec();
});
});
Thank you in advance :)
function isElementInViewport(elem) {
var $elem = $(elem);
// Get the scroll position of the page.
var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html');
var viewportTop = $(scrollElem).scrollTop();
var viewportBottom = viewportTop + $(window).height();
// Get the position of the element on the page.
var elemTop = Math.round( $elem.offset().top );
var elemBottom = elemTop + $elem.height();
return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}
function checkAnimation_aec() {
var $elem = $('.aec');
// If the animation has already been started
if ($elem.hasClass('icon_start')) return;
if (isElementInViewport($elem)) {
// Start the animation
$elem.addClass('icon_start');
}
}
// Capture scroll events & run the functions
$(document).ready(function(){
//after document is ready, run the animation element is visible.
checkAnimation_aec();
$(window).scroll(function(){
checkAnimation_aec();
});
});

typed.js execution when scrolled

I'm a beginner - just saying.
I'm trying out different .js files available online and I found typed.js.
But what if I have my own website and want to execute typed code when I scroll to a certain element of the page?
I got this:
<script type="text/javascript" src="js/typed.js"></script>
<script>
$(function(){
$("#typed").typed({
strings: ["Are you somehow interested?"],
typeSpeed: 30
});
});
</script>
in the end of my HTML file.
How to run this code when I reach the specific div or h1 or whatever?
Is there any online source where I can learn how to do it?
Thanks!
First of all have a method which will check if the user is scrolled to a div as following:
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));
}
Then add event listener to window scroll as following:
$(window).scroll(function() {
if(isScrolledIntoView($('#theTarget')))
{
//the div is now visible to user. here add your script
$("#typed").typed({
strings: ["Somehow interested?"],
typeSpeed: 20
});
}
});
Try this:
var hasScrolledPast = false;
window.onscroll = function() {
if (window.scrollTop > whereYouWantToScrollDownTo && !hasScrolledPast) {
hasScrolledPast = true;
// do your code here.
}
};
<script>
$(window).on('scroll', function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = 1800; // set to whatever you want it to be
if(y_scroll_pos > scroll_pos_test) {
//do stuff
$(function(){
$("#typed").typed({
strings: ["Zainteresowany?"],
typeSpeed: 20
});
});
setTimeout(function() {
$(function(){
$("#typed2").typed({
strings: ["Skontaktuj siÄ™ z nami!"],
typeSpeed: 20
});})}, 4000);
}
});
</script>
This solved the problem of waiting for another function to execute, but now there is another problem.

Automatically loading more posts (checking if element is visible on screen)

This function detects whether or not an element is visible on the screen. When a user scrolls to a "load" element I want to automatically request more posts to be displayed (AJAX). However, at the moment I have the following code:
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));
}
var scrolledCounter = 0;
setInterval(function(){
var scroll = isScrolledIntoView(".button.load-more");
if(scroll==true){
scrolledCounter++;
loadMorePosts(scrolledCounter);
}
},500);
It works fine, but if the element is constantly in view (as it would be for slower-ish connections loading the information), it then loads more every 500ms. I'm wondering what method would be better than setInterval (?) to accomplish what I want to do.
i.e.
If the user scrolls to the load element, function loadMorePosts is called just once, then if it's not visible anymore, re-allow the function to be called again, such that if it's visible again the function is called once more again.
You can use $(window).scroll() method. It will occur every time users scrolls the page.
I have added an isScrolling variable to prevent firing loadMorePosts more than once in a period.
var isScrolling = false;
$(window).scroll(function(){
var scroll = isScrolledIntoView(".button.load-more");
if (scroll==true && !isScrolling)
{
isScrolling = true; // Block this function
scrolledCounter++;
loadMorePosts(scrolledCounter);
setTimeout(function() { isScrolling = false; }, 500); // Unblock the function after 0.5s
}
});
JSFiddle DEMO (without isScrolling): http://jsfiddle.net/0wbf9dn2/

Check if div is viewable in window?

I have a one page site with fixed navigation and using a scroll script, very similar to this: http://www.ivanjevremovic.in.rs/live/temptation/single/orange/index-cycle-slider.html
What I'm looking for is a way to check what section is viewable in the window to set the active state on the nav when using the browsers scroll bar, any ideas?
Here are all the variables you'll need...
var $myElt = $('.myElement'); // whatever element you want to check
var $window = $(window); // the window jQuery element
var myTop = $myElt.offset().top; // the top (y) location of your element
var windowTop = $window.scrollTop(); // the top of the window
var windowBottom = windowTop + $window.height(); // the bottom of the window
Then to make sure your element is within the window's range...
if (myTop > windowTop && myTop < windowBottom) {
// element is in the window
} else {
// element is NOT in the window
// maybe use this to scroll...
// $('html, body').animate({scrollTop: myTop}, 300);
}
jQuery reference:
http://api.jquery.com/offset/
http://api.jquery.com/height/
http://api.jquery.com/scrollTop/
Use $('#element').offset().top; to detect element top side.
$(window).scrollTop(); to detect current scroll position.
And $(window).height(); to detect current window height.
And after that steps you actually need only something easy math calculations.
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));
}
source: Check if element is visible after scrolling
see the following lazyload plugin:
http://plugins.jquery.com/files/jquery.lazyload.js__6.txt
the section which starts with the comment "return the status of the item relative to the current view" checks to see if an element is visible in the viewport.
If you are using jQuery just try to check the document position
$('html').position().top;
for example:
$(document).bind("scroll", checkLink);
function checkLink(){
/* Position will checked out after 1 sec when user finish scrolling */
var s = setTimeout(function(){
var docHeight = $('html').position().top;
var allLinks = $('.navigation a');
if ( docHeight < 0 && docHeight <= -1000 ) {
allLinks.removeClass('active');
$('a.firstlink').addClass('active');
} else
if ( docHeight < -1000 && docHeight <= -2000 ) {
allLinks.removeClass('active');
$('a.secondlink').addClass('active');
} else { /* .... */ }
$(document).bind("scroll", checkLink);
}, 1000);
$(document).unbind('scroll');
}
but guys in your example haven't held on this for a long time :) they just toggle classes on click
$('#navigation').localScroll();
$('#navigation li a').click( function () {
$('#navigation li a').removeClass("active");
$(this).addClass("active");
});
2022 answer - you don't have to use jQuery anymore for this
Now it is possible to use plain javascript with IntersectionObserver.
The problem with the other answers are that they fire off too many times.
For example you could to this:
var observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting === true) {
console.log('Element is in the window');
} else {
console.log("Element is not in the window");
}
});
observer.observe(document.querySelector(".myObject"));

Categories

Resources