Run JQuery animation on numbers when I scroll once on a div - javascript

I have an one-page-style website and somewhere in the middle I have a few numbers as statistics. I try to make them counting until they reach the stats when a user find the div for the first time after refreshing the page. I don't have the option to use a plugin, so I am trying to do it with JQuery only.
Here is the code:
$(window).scroll(function(){
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $("#our-company").offset().top;
var elemBottom = elemTop + $("#our-company").height();
if ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)) {
start_count();
}
});
function start_count(){
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 4000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
The div with the id = our-company is the one containing the stats and all the numbers are in a span with a class of class = count. The problem in my code is that after I scrolled down on the stats and see the numbers counting, if I scroll up and down again, they start from the beginning. How can I make it run once?

Why not just put a flag var ?
var alreadyRun = false;
[...]
if (alreadyRun == false && (elemBottom <= docViewBottom) && (elemTop >= docViewTop)) {
alreadyRun = true;
start_count();
}
[...]
Cheers

Related

Stopping a Javascript timer function from running multiple times after using an 'in viewport' function to call it?

Creating a website with a timer that counts up once the div is scrolled into view. The problem I'm having is that scrolling away starts the timer again, and I'd like the final value that the timer reaches to remain until the page is reloaded.
I've tried using 'event.handled' and '$.Callbacks("once")' but neither seem to work.
Any guidance would be appreciated - code below!
$(allInView);
$(window).scroll(allInView);
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 allInView() {
if (isScrolledIntoView($("#column4"))) {
/// when 'column4' IS being 'viewed', the timers then begin
jQuery(function ($) {
$(".timer").countTo({
from: 0,
to: 183,
speed: 1000,
refreshInterval: 50,
onComplete: function (value) {
console.debug(this);
},
});
});
}
}
You could use a variable to check if the timer is already started.
let lockTimer = false;
function allInView () {
// Exits conditions to avoid to restart the timer
if (lockTimer || !isScrolledIntoView(...)) {
return;
}
lockTimer = true; // block timer launch
JQuery(...);
}

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.

Load Javascript when element is in view

So I've had some assistance to create a javascript element which spins from "0" upto "190" however, this is triggered when the element is in view - so I thought - it turns out the number is ONLY increased when you scroll.... For example:
Script:
var totalShipped = 190;
var shippedDisplay = 0;
var shippedStep = totalShipped / (2 * 1000 / 100); // Animation duration 2 sec
$(allInView);
$(window).scroll(allInView);
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 allInView() {
if (shippedDisplay > totalShipped)
shippedDisplay = totalShipped;
document.getElementById("shipped").innerHTML = Math.round(shippedDisplay);
if (shippedDisplay < totalShipped) {
shippedDisplay += shippedStep;
setTimeout(animateShipped, 100);
}
}
animateShipped();
HTML:
<span id="shipped"></span>
What I want is for the element to automatically spin from 0 - 190 ONLY when the element is in the view of the browser and NOT actioned by scrolling....
As it is right now:
https://gyazo.com/6cd38177c44e97f0fa4f2b4d05ece5c3
Ideally I want all the number to be spinning, but let's focus on the "190" for now, when in view of the browser - any tips or suggestions would GREATLY be appreciated.
What I would suggest is set a timer on page load and use this Jquery Visible plugin to check if your element is in view before incrementing.
Hope that helps.
Assuming your isScrolledIntoView(elem) function is working you can do something like this:
window.setInterval(function(){
if(isScrolledIntoView($('#shipped'))){
allInView();
}
}, 100);
What it will do is checking every 100ms if your span is visible and then calling your allInView() function which then will animate the spinning.
If you do not want any overhead if the element is not visible you can deactivate the interval accordingly:
var interval = null;
function checkForAnimation(){
if(isScrolledIntoView($('#shipped'))){
interval = window.setInterval(function(){
allInView();
}, 100);
}
else{
clearInterval(interval);
}
}
$(window).scroll(checkForAnimation);
You can use setInterval(allInView(), 2);

Detecting when div is scrolled to does not work

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

Categories

Resources