An animation for a loading message is done by JQuery. When the page is about to be redirected to another page, the loading message is displayed. Here what the animation does is, increase the width of a DIV element.
$('#loading').css({"width:":value});
Above,'value' is increased through setInnterval(), My problem is, when the page is going to redirect to the other page(some time for 4 ,5 seconds) the animation doesn't happen. Any one let me know why this happen and how this can be avoided ?
why not just use the inbuilt jQuery animate instead of your own setInterval?
$('#loading').animate({ width: finalValue });
you just need to tell it what you want the final width to be.
You need show more detail of your code, basicly redirect may happens before the animation, you may watch the value, then when the value up to the maximum, do the redirect.
var value = 0;
var timer = setInterval(function(){
if(value >= someValue){
clearInterval(timer);
location.href = 'someURL';
}else{
$('#loading').css('width', value++);
}
});
haven't test yet.
Related
I am creating a game called 'Pointless'. Pointless here is a game show in the UK. Anyway, there is a countdown which counts down from 100 to whatever score the team got. I am trying to replicate this. For an example, please see this video.
Anyway, I am trying to replicate the countdown myself, however whenever I try the whole thing gets executed at once instead of one div at a time like it should. I need to hide those divs one by one.
Please see this JSFiddle.
for (var i = 0; i <= 10 ; i++) {
$('#' + i).toggle('slide');
}
When you call toggle or any other animate functions in jQuery, it does not block the rest of the code. The animation continues on, while the rest of the code is running. You can add a delay for each of those blocks to start the animation.
You can try this one:
I also suggest you to use .slideToggle('slow') instead of .toggle('slide').
$('#' + i).delay(i*100).slideToggle('slow');
Because the .toggle() events (along with other events) are accually enqued and triggered after the execution of the entire for-loop. Or rather even if they where not, you are calling toggle on all of them nearly all at once, so they will all toggle at the same time. One way to get around it it to use a timer such as setInterval or setTimeout:
$('#Go').click(function(){
var i = 0;
var timer = setInterval(function(){
i++;
$('#' + i).toggle('slide');
if(i > 10) clearInterval(timer);
},100)
})
Fiddle Example
Amir solution is greate. I want juste to add a small correction :
toggle method of jQuery doesn't have any arguments whose value could be slide.
Here is the correct syntaxe :
$(selector).toggle(speed,easing,callback)
speed in [milliseconds, "slow", "fast"]
easing in ["swing", "linear"] (More easing functions are available in external plugins)
callback is a function
This is new to me, and I don't know how to handle it.
The page has a logo that uses transitions to change its size and color and is triggered by this on the bottom of the HTML:
document.onload="initialize()"
setInterval(function(){
setTimeout(function(){
$('#path1').css('transform','scale(.95)');
$('#path2').css('transform','scale(.95)');
$('#path2').css('fill','#F7A700');
}, 2000);
$('#path1').css('transform','scale(1.05)');
$('#path2').css('transform','scale(1.00)');
$('#path2').css('fill','#FFCF55');
}, 4000);
This starts the transition and changes the color of the svg path in coordination. On a separate script page there is a function that determines the current page slider and I need to change the css fill on #path2 for a specific page. I've tried if...else statements, moving the setInterval() function to the same page, etc, but nothing is letting me override the fill color in the setInterval() function.
REVISION: Its included in the html and there is a separate js page with all of the other functions. So I thought maybe it had something to do with that but now I'm understanding it is running on an infinite loop so any changes I try to make are going to be overridden. Its a logo that is a svg with multiple paths and on the homepage slide one path needs to be white and everything else stay the same for all other pages slides. There is only one page of html and the content slides on a slider. Not sure if I explained it any better. I'm working with existing code done by someone else so I'm trying to work with what I've been given but maybe there is a better solution to run this? maybe through css? I need it to load on window or document load and run infinitely but need to be able to modify the css on it. I have to use css transforms to set it up.
The interval is setup to run forever. If you set the color from another script, the interval will just overwrite the color the next time the interval runs. One option is to stop the interval when setting the color from the other script. You would need a variable to hold the interval id.
var timer = null;
You would need to save the interval id when starting the interval.
timer = setInterval(function(){
setTimeout(function(){
$('#path1').css('transform','scale(.75)');
$('#path2').css('transform','scale(.75)');
$('#path2').css('fill','#F7A700');
}, 2000);
$('#path1').css('transform','scale(1.50)');
$('#path2').css('transform','scale(1.50)');
$('#path2').css('fill','#FFCF55');
}, 4000);
In your other script, stop the interval when setting the color.
if (timer) {
clearInterval(timer);
timer = null;
}
$('#path2').css('fill','#00FF00');
Edit:
Another possible option is to use boolean flags to stop parts of the animation. This would allow you to stop the fill animation but continue with the reest of the animation. You would need a boolean flag to indicate whether or not the fill should be animated. Initialize the flag to true.
var animateFill = true;
Use the flag to determine if interval should animate the fill attribute.
setInterval(function(){
setTimeout(function(){
$('#path1').css('transform','scale(.75)');
$('#path2').css('transform','scale(.75)');
if (animateFill){
$('#path2').css('fill','#F7A700');
}
}, 2000);
$('#path1').css('transform','scale(1.50)');
$('#path2').css('transform','scale(1.50)');
if (animateFill) {
$('#path2').css('fill','#FFCF55');
}
}, 4000);
In your other script, set the flag to false when setting the fill color.
animateFill = false;
$('#path2').css('fill','#00FF00');
If you later need to restart the animation of the fill color then set the flag back to true.
animateFill = true;
I have a page with a lot of elements (~1,500) of the same class on it, and when I execute
$(".pickrow").addClass("vis");
it takes a second or two for the page to reflect the changes. So that users aren't thinking the page was stuck, I'd like to pop-up a small message using:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").hide();
But the msgDiv never shows. If I remove the $("#msgDiv").hide(); the msgDiv appears simultaneously with the application of the added class (after the 1 or 2 seconds it took to add the class).
It seems like the jQuery functions get pooled and run together without any screen updates until they have all completed.
How can I get the msgDiv to appear while the $(".pickrow").addClass("vis"); is processing?
Here's a Demo
You probably want to delay the hide by a few seconds.
$("#msgDiv").show();
$(".pickrow").addClass("vis");
setTimeout(function(){ $("#msgDiv").hide(); },2000);
Or using jQuery's animations queue for timing:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").delay(2000).hide(1); //must make it at least 1 ms to go into the queue
You can go with this approach also
Working DEMO
$(document).on("click",".btn",function(){
$(".msg").show("fast",function(){
$(".pickrow").addClass("vis");
var interval = setInterval(function(){
var picLength = $(".pickrow").length;
var visLength = $(".vis").length;
if(picLength == visLength){
clearInterval(interval);
$(".msg").hide();
}
},500);
});
});
I think if you simplify the code, you would find that it is much more responsive and probably not require the loading message. In your code, you check every single element in an if statement. Rather than do that, you can check one value, then update all of them accordingly.
Here's a demo: http://jsfiddle.net/jme11/3A4qU/
I made a single change to your HTML to set the initial value of the input button to "Show Details". Then in the following code, you can just check whether the value is Show Details and remove the class that hides the .pickrow and update the value of the button to be "Hide Details" (which is better feedback for the user anyway). Likewise, you can add the .hid class to the pickrow if the button value is not "Show Details". This will also normalize all of the classes regardless if some were individually hidden or shown.
$('#showhide').on('click', function(){
if ($(this).val() === 'Show Details') {
$('.pickrow').removeClass('hid');
$(this).val('Hide Details');
} else {
$('.pickrow').addClass('hid');
$(this).val('Show Details');
}
});
A quick thank you to those that have helped me so far with this script, you have all helped me enormously in learning some of the more elegant sides of javascript and jquery.
I have one final problem with this script, I am using setinterval() to cycle through an image changer, the JS/Jquerycode is as follows:
$(function() {
var rotateTimer = setInterval(rotateImg,15000);
$('#feature-links a').click(function() {
if (!$(this).hasClass('a-active')) {
clearInterval(rotateTimer);
switchToImg($(this).attr('class'));
}
});
function switchToImg(image) {
var $featureImage = $('#feature-image');
$featureImage.fadeOut(200, function() {
$featureImage.css('background-image', 'url(images/main_' + image + '.jpg)').fadeIn(200);
$('#feature-detail div').removeClass('d-active').filter('.d' + image).addClass('d-active');
});
$('#feature-links a').removeClass('a-active').filter('.' + image).addClass('a-active');
};
function rotateImg() {
var next = 'a' + (parseInt($('#feature-links a.a-active').attr('class').match(/[0-9]/))+parseInt(1));
if (!$('#feature-links a').hasClass(next))
next = 'a1';
switchToImg(next);
}
});
This script works on class names of <a> tags that allow a user to manually switch to an image. As well as this, rotateImg() is providing an automated image/text cycle every 15 seconds with the help of setInterval().
The problem I have is with setInterval() re-initialising once a user has clicked on a link manually.
In the .click function I clear the interval timer and then make a call to the switchToImg() function with the class name of the <a> tag that was clicked on passed as a variable.
I'm trying to work out how I can re-set the timer to avoid a user clicking on a link towards the end of the cycle and having it switch immediately to the next image.
I have researched building my own callback function in to switchToImg() so that once the function has completed the timer is reset, ideally I'd like this to be a longer time initially (30 seconds for example) but then settle back down into the 15 second clock. My research however has lead me to a load of different repositories that I'm having difficulty making head or tail of.
Any guidance as to how I can build this functionality into the script would be really appreacited. Thanks for your time. :)
I'm not 100% sure I follow what you're asking, but if what you're trying to do is to restart the interval timer after a delay after the user clicks, then you could do that like this:
$('#feature-links a').click(function() {
if (!$(this).hasClass('a-active')) {
clearInterval(rotateTimer);
switchToImg($(this).attr('class'));
setTimeout(function() {
rotateTimer = setInterval(rotateImg, 15*1000);
}, 15*1000);
}
});
You would be using a one-shot setTimeout() call to restart the interval timer after a 15 second delay. This would give you 15+15=30 seconds before the next image switched again after a click and then 15 seconds each time after that.
Not sure I understand the question correctly. But basically I get that you want to prevent the timer from happening after the user clicks. Shouldn't calling setInterval right after switchToImg do exactly that? It'll call switchToImg then after every 15 seconds from the click of the user.
I have a page with a countdown in a DIV with id ="count"
I would like to monitor this div value so, when it reaches 0, a alert pops up.
I've gono so far as
if(parseInt(document.getElementById('count').innerHTML) < 2){}
But I don't know how to "listen" for the div changes
Can anyone help me?
Btw: it needs to be in pure javascript, with no such things as jquery.
Update:
I have no say so in the original code. It's an external page and I'm trying to run this code at the address bar
Presumably you have a function running based on setInterval or setTimeout. Have that function call your function when it gets to zero.
If you can't do that, you can try optimised polling - use setInterval to read the value, estimate when it might be near zero, check again and estimate when it might be zero, etc. When it is zero, do your thing.
There are DOM mutation events, but they are deprecated and were never well or widely supported anyway. Also, they are called when content changes so probably too often for your scenario anyway.
If you are changing the value of #count yourself then call the alert from that place. If not use:
window.setInterval(function(){
if(parseInt(document.getElementById('count').innerHTML) < 2) alert('Alarm!');
},1000); // 1s interval
UPDATE
To clear that interval:
var timer = window.setInterval(function(){
if(parseInt(document.getElementById('count').innerHTML) < 2) {
alert('Alarm!');
window.clearInterval(timer);
}
},1000); // 1s interval
//or by using non-anonymous function
function check(){
if(parseInt(document.getElementById('count').innerHTML) < 2) {
alert('Alarm!');
window.clearInterval(timer);
}
}
var timer = window.setInterval(check,1000);
The only efficient way to monitor this is to go to the code that is actually changing the div and modify it or hook it to call a function of yours whenever it updates the contents of the div. There is no universal notification mechanism for anytime the contents of div changes. You will have much more success looking into modifying the source of the change.
The only option I know of besides the source of the change would be using an interval timer to "poll" the contents of the div to notice when it has changed. But, this is enormously inefficient and will always have some of inherent delay in noticing the actual change. It's also bad for battery life (laptops or smartphones) as it runs continuously.
You don't listen for the div to change. The div is just there for a visual representation of the program's state.
Instead, inside whatever timing event is counting down the number, use a condition such as...
if (i < 2) {
// ...
}