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);
Related
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(...);
}
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/
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
Im trying to fire a function once on resizing. The problem is the conditional statements are not being executed everytime for some reason. the code is
var old_width= $(window).width();
$(window).on('resize.3col',function(e){
clearTimeout(timer);
timer=setTimeout(function(){
var nw= $(window).width();
if((nw <= old_width) && (nw <= '940') && (nw >= '915') ){
appendList('resize.3col');
}
old_width= nw;
} , 500);
});
the reason im using settimeout is because I want to get the new width, if I dont use it the new width is the same as old width which I don't want. If I dont use settimeout, the conditions work.
EDIT:
the conditional statements fire sometimes at other times they do not. How do I make it more smooth?
Try this code and see if there is any difference:
var $win = $(window),
oldWidth= $win.width(),
winResized = function(){
var newWidth= $win.width();
if (
newWidth <= oldWidth &&
newWidth <= 940 &&
newWidth >= 915
){
appendList('resize.3col');
}
oldWidth = newWidth;
},
timer;
$win.on('resize.3col',function(e){
clearTimeout(timer);
timer = setTimeout(winResized, 500);
});
I was using the same timer variable for calling the resize event with different namespaces '3col', '4col' and '5col'. Also I added if(timer) clearTimeout(timer); which improved the functionality. Thanks :)
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"));