I have a jquery function that will animate the progress bar I have from 0 to 100 when it is on the screen. The problem is, if it is not visible (not visible on the page) on page load, it will never be triggered.
My code
<script>
$(function() {
$('.dial').knob({
min: '0',
max: '100',
readOnly: true,
displayInput: true
});
$(".dial:in-viewport").parent().show(0, function() {
$({ value: 0 }).animate(
{ value: 100 },
{ duration: 1000,
easing: 'swing',
progress: function() {
$('.dial').val(Math.round(this.value)).trigger('change');
}
});
});
});
</script>
My question is how do I make it so that function will constantly check to see if it is on the screen until it returns valid.
The easiest way would be to create an interval which executes the code every n milliseconds.
var interval = 400;
var timer = window.setInterval(function(){
// your code goes here ...
if (yourCodeHasBeenExecuted === true) {
window.clearInterval(timer);
}
}, interval);
I guess this will work, but it is not the most beautiful solution existing. A better way would be to use window resize or window scrolling events, depending of what you need, and execute your code there.
You find an example for a resize event here.
Related
I have created a script to animate a number from zero to a certain number obtained from a PHP file. But doesn't works.
This is my code:
JQUERY
(function($){
var auto_refresh = setInterval(
function (){
$("#tasksCompleted").load("https://workhub.atexto.com/main/tasksCompleted.php").fadeIn("slow");
},
3000); // refresh every 1000 milliseconds
jQuery({ Counter: 200000 }).animate({ Counter: $("#tasksCompleted").text() }, {
duration: 8000,
easing: "swing",
step: function () {
$("#tasksCompleted").text(Math.ceil(this.Counter));
}
});
})(jQuery);
HTML
<span id="tasksCompleted"></span>
Here is the demo (dont's work):
https://jsfiddle.net/rwf707Lp/
EDIT
I changed a coupled things from my first answer...
The trick, to show an "achievement counter" will be to count from zero to the number obtained via ajax on page load.
Then the interval to constantly check for an updated achievement has to check if the quite long onload animation had finished.
If not finished the initial counting... Just let it finish! And wait for the next inteval iteration.
Then... If the obtained number is different from the number "before ajax", count!
The speed now depends on the number form the ressource speed to increase.
I think that is closer to what you wish...
;)
(function($){
console.clear();
var number_beforeAjax;
var number_afterAjax;
var auto_refresh = setInterval(
function (){
number_beforeAjax = parseInt( $("#tasksCompleted").text().replace(",","") );
console.log("number_beforeAjax: "+number_beforeAjax);
$.ajax({
dataType: "jsonp",
url: "https://www.bessetteweb.com/SO/45614889/ressource.php",
success: function(data){
$("#numberFromAjax").html(data);
counter();
}
}); //$("#numberFromAjax").getJSON("https://www.bessetteweb.com/SO/45614889/ressource.php",counter());
},
3000); // refresh every 3000 milliseconds
// A separate function to call as a load callback
function counter(){
// Just to see what was loaded via ajax.
var loaded = $("#numberFromAjax").text();
console.log("loaded: "+loaded);
// Number loaded via ajax parsed as integer.
number_afterAjax = parseInt( $("#numberFromAjax").text().replace(",","") );
console.log("number_afterAjax: "+number_afterAjax);
// If the numbers before and after ajax are different
if(number_beforeAjax != number_afterAjax && !isNaN(number_afterAjax) ) {
counterSpeed = 5000;
// Faster if the difference isn't much
if(number_afterAjax-number_beforeAjax<20){
counterSpeed = 2900;
}
// Set the start number to zero on 1st iteration
var startNumber;
if(isNaN(number_beforeAjax)){
startNumber = 0;
}else{
startNumber = number_beforeAjax;
}
// Counter!
jQuery({ Counter: startNumber }).animate({ Counter: number_afterAjax }, {
duration: counterSpeed,
easing: "swing",
step: function () {
$("#tasksCompleted").text(Math.ceil(this.Counter).toLocaleString());
}
});
}
// Just a console.log
if(number_beforeAjax == number_afterAjax && !isNaN(number_afterAjax)){
console.log("Request revealed no change.")
}
}
})(jQuery);
#numberFromAjax{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="tasksCompleted"></span><br>
<span id="numberFromAjax"></span>
Got to wait 3 seconds for the first interval to start in this snippet...
When you'll see "Request revealed no change.", just wait a little for the ressource to increment.
EDIT
.toLocaleString() re-adds the coma on the number to be displayed.
Seems to work fine you just missed to import Jquery lib ,
see below snippet :
(function($){
var auto_refresh = setInterval(
function (){
$("#tasksCompleted").load("https://workhub.atexto.com/main/tasksCompleted.php").fadeIn("slow");
},
3000); // refresh every 1000 milliseconds
jQuery({ Counter: 200000 }).animate({ Counter: $("#tasksCompleted").text() }, {
duration: 8000,
easing: "swing",
step: function () {
$("#tasksCompleted").text(Math.ceil(this.Counter));
}
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="tasksCompleted"></span>
So I have the code below for a auto typing text animation. The text is in front of a image and I want people to see the full picture first and then the text starts to "type". I guess the best way is to add a 2-3 seconds delay before the text starts to animate but I'm not really sure how to do that.
Help would be very much appreciated. Thanks!
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
});
var text = 'TEXT GOES HERE';
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
Adding some arbitrary delay is NOT the best way. You never know how much time an image will take to load on different kinds of networks, some are very fast, others might be very slow.
Instead you should fire your code on some event e.g. when the image has loaded. You can run your code on window load as an option as shown below:
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
$(window).on("load", function(){
// do here tasks that you want to run after all page assets e.g. images have been loaded
showText();
});//window load()
});
function showText() {
var text = 'TEXT GOES HERE';
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
}
Try using setTimeout() function to call your function after some time i.e
$(document).ready(function() {
setTimeout(yourfunction(), 1000); //changes milliseconds as per your need.
})
https://www.w3schools.com/jsref/met_win_settimeout.asp
Generaly. It is done that you pack delayed code into callback and that callback you pass into setTimeout method. For preserving functionality while working in objects. I recomentd to call bind(this) on packaged callback.
setTimeout(function () {
console.log("Delayed message");
}.bind(this), 3000);
In your case
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
});
var text = 'TEXT GOES HERE';
setTimeout(function () {
// delayed code
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
// end of delayed code
}.bind(this), 3000);
Thank for the recomendations, I have updated my ask.
I have the next code:
https://jsfiddle.net/btq7mm0h/3/
Is a simply counter starts when the document is ready. I would like that it will start when the div id="testimonios" is visible on screen because when I do scroll to down for to see the effect is already can't see.
What I have made, I find several plugin js like
https://www.customd.com/articles/13/checking-if-an-element-is-visible-on-screen-using-jquery
Add script in my document and modified the code:
if $('#testimonios').visible( true ) {
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 9000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
Please any suggestion.
There's a few ways to go about this such as using a timer, pure javascript and jquery has a few variations. Here's one way to go about this.
$("#testimonios").bind("DOMSubtreeModified", function() {
// do whatever here, you can even add an if statement for css such as
var cssCheck = $(this).css('display');
if (cssCheck == "block") {
// Div Display is Visible
alert("isVisible");
} else {
// Div Display is not Visible
alert("isNotVisible");
}
});
You can see the result at codebin: http://codebins.com/bin/4ldqoyk
I am trying to animate a number so that it rolls into the number when the page loads. I am using another library to display a dial (http://anthonyterrien.com/knob/). The issue I am having is that the number seems to be different every time I run it. It should be a consistent number ending on 19420. However sometimes it is lower and there doesn't seem to be any particular pattern.
My JS code looks like this:
$(function() {
$('#dial').knob({
min: '0',
max: '25000',
readOnly: true
});
$({
value: 0
}).animate({
value: 19420
}, {
duration: 950,
easing: 'swing',
step: function() {
$('#dial').val(Math.round(this.value)).trigger('change');
}
});
});
The fiddle can be found here: http://jsfiddle.net/ND5Sf/
What have I done wrong or is there anything I've missed out? If not, are these 2 libraries not compatible?
The issue is because you are using step function instead of progress.
Step:
A function to be called for each animated property of each animated
element. This function provides an opportunity to modify the Tween
object to change the value of the property before it is set.
Progress:
A function to be called after each step of the animation, only once
per animated element regardless of the number of animated properties.
(version added: 1.8)
Code:
$(function () {
$('#dial').knob({
min: '0',
max: '25000',
readOnly: true
});
$({
value: 0
}).animate({
value: 19420
}, {
duration: 950,
easing: 'swing',
progress: function () {
$('#dial').val(Math.round(this.value)).trigger('change');
}
});
});
Docs: http://api.jquery.com/animate/
Demo: http://jsfiddle.net/IrvinDominin/JW2gP/
Good morning all :) I've got an issue here, which is pain in my neck for 2 days already. I'm using bxSlider for images to slide on a page and I'm calling my own function in onAfterSlide callback. Everything works fine except one thing. When I quickly switching between slides my function is being called 2-3 times(I have 3 images on page), which is not good as it returns unexpected results. I can not use newest version of bxSlider, because the markup has been changed. I think this happens, because the animation is still not finished when the onAfterSlide callback is called.
This is how I call bxSlider:
$('#slider_bx').bxSlider({
mode: 'fade',
speed: 1000,
pause: 9000,
auto: true,
autoControls: false,
prevText: '',
nextText: '',
autoHover: true,
captions: false,
pager: true,
onBeforeSlide: function () {
if ($('.slide_in').length) {
$('.slide_in').hide();
}
},
onAfterSlide: function () {
if ($('.slide_in').length && $('.slide_in').is(':hidden')) {
doCrazyStuff();
}
}
});
And this is my function:
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
setTimeout(function () {
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
Any help appreciated. Thanks.
EDIT:
I've tried to add .stop(), but didn't helped.
$this.show().stop();
$this.stop().show();
$this.stop().rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
}).stop(); // throws an error
You can cancel a timeout or make a check to see if it's running.
If you want only the last timeout to run:
var crazyTimeout;
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
if (crazyTimeout != undefined) {
clearTimeout(crazyTimeout); // Cancel previous timeout
}
crazyTimeout = setTimeout(function () {
crazyTimeout = undefined;
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
If you want only the first timeout to run:
var crazyTimeout;
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
if (crazyTimeout != undefined) {
return; // A timeout is still running: don't create new one
}
crazyTimeout = setTimeout(function () {
crazyTimeout = undefined;
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
Try using the
$('.slide_in').stop()
in after slide function I hope it works, if possible try to give code in fiddle it will be easy to help.
Viewing your code I think the problem is not with your code : but as you have set auto to true so the plugin timer is not stopped and is sliding the images in its regular interval.
so I hope the use of stopAuto() bxSlider function in your custom function will solve the problem. and don't forget to start the auto show after you have finished doing your stuff.
thanks