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.
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
I've been working on this slider for a bit, and I've got it to auto play with some nice simple Jquery markup. I decided I wanted to have the option to go to previous and next on the slider, but I'm not sure if it's possible with the set up I have. I've got a "Next" Button set up that moves to the next image. My problem lies in getting the timer to restart after you hit next in the code. Is this possible to do, am I just overlooking something? I also am wondering how to I create the equivalent of the "next" button for a "previous" button. Any help would be appreciated, since I've been banging my head against this one for while.
Here is the Jquery I'm using:
var time = 6000;
function play() {
setInterval(function(){
var next = $(".slideshow .active").removeClass("active").next(".image");
if (!next.length) {
next = $(".slideshow .image:first");
}
next.addClass("active");
}, time);
}
play();
/*Start of function for next button */
function forward() {
$('.forward').click(function() {
var go = $(".slideshow .active").removeClass("active").next(".image").addClass("active");
if (!go.length) {
go = $(".slideshow .image:first");
}
go.addClass("active");
});
}
forward();
I've created a CodePen(http://codepen.io/Develonaut/pen/lLmkc) to try and work this out. I will gladly give credit on the CodePen for whoever helps. Thanks so much!
Check out clearInterval.
You need to set the return value of your setInterval to a variable, then pass that variable to clearInterval to reset your timer. Do that on each press of your previous/next buttons, then call the play function again to start the timer from the beginning.
Here's an updated version of your CodePen example.
Do something like this:
Store the interval id - setInterval() returns this for later use with clearInterval()
var intervalId = setInterval(function()...
Then clear & reset the interval when the button is pressed:
clearInterval(intervalId);
play();
I'm a designer more than a programmer, but I'm trying to get the hang of javascript so I have more design options when it comes to web design beyond plugins. So here's the problem I'm having.
I have a page with 4 slide shows. Right now I have it so that when one of 4 buttons are clicked it will change the array it gets the image sources from and loop through the images every 4 sec.
At first the slideshows look fine and the change happens when the image is hidden, but after a couple minutes the source change falls out of time with the fading effects and happens when its visible. It also works fine to have the shows switch with no problem.
All the timing and variables get reset and the new parameter from the onClick-call switches which array is used. I tried one solution where I made the image change part it's own function and called it from other functions to control the timing more, but then for some reason clearTimeout stopped working to clear the loop and it would still play one instance of the loop at the same time as another.
Maybe someone can look at this code and see a simple fix for the timing issue.
i=0
var delay=4000
var fade=1000
var timer;
function play(showNum){
var showNum = showNum;
$("#show").stop(true,true)
newShow();
changeInfo(showNum);
$("#show").hide();
change(showNum);
}
function change(showNum){
$("#show").fadeIn(fade);
$("#show").attr("src",showNum[i]);
i = (i+1)% showNum.length;
$("#show").delay(delay-(fade*2)).fadeOut(fade);
timer=setTimeout (function(){change(showNum)},delay)
}
function newShow(){
clearTimeout(timer);
i=0;
}
Here is an update to the code since I posted this.
function play(showNum){
var showNum = showNum;
$("#show").stop(true,true);
newShow();
$("#show").hide();
changeInfo(showNum);
change(showNum);
$("#show").fadeIn(fade);
setTimeout(function(){loop(showNum);},fade*2);
}
function loop(showNum){
$("#show").fadeOut(fade);
setTimeout (function(){change(showNum);},fade);
$("#show").fadeIn(fade);
int=setTimeout (function(){loop(showNum);},delay);
}
function change(showNum){
$("#show").attr("src",showNum[i]);
i = (i+1)% showNum.length;
}
function newShow(){
clearTimeout(int);
i=0;
}
I don't get a problem with the timing anymore, but I do get a weird hiccup if I click on a new slideshow when it's on fadeOut where it changes image then changes back and then fades in with the next image of the previous slide show then fades out and starts the right slide show from there.
What's happening
Okay, so I've made a function on my front page where some products are shown besides each other, fading out, changing products and fading back in every 5 seconds. The code looks like this:
var t;
$(document).ready(function(){
// Some pre-animation stuff, like loading the products etc.
// Initialize animation timer
t = setInterval("changeProducts();", 5000);
};
function changeProducts() {
// Fade out
$("#anfBox").fadeTo(200, 0.01, function() {
// Change products
// Fade back in
$("#anfBox").fadeTo(200, 1);
});
}
It all looks fine and runs as it should, except when i go to another window for a minute and then comes back, the changeProducts function is executed rapidly a few times (depending on how long i've been away). The products fade out, change fades in again, and then repeats instantly, where there should be a ~5 second delay.
What I've tried
So what I think I need to do is use something like clearInterval(t) when the focus is lost from the window, then re-initialize the timer when the window is re-entered, i just don't know how to do that, and i'm having a hard time finding anything useful on google.
I'm thinking maybe there's allso a way to run the animations even if the window is not in focus to avoid the function-queue.
I've also tried using setTimeout() instead but with no luck.
Any ideas on how to avoid the animation-queue is much appreciated.
With the latest browser updates lots of browsers now stop execution of code when current page or tab is not active. When you return that tab/window it executes all of queued actions and you see a rush of effect running each after.
Simply check effect queue before apply another effect, if queue's length is 0 then apply.
Try this (example);
var t;
function changeProducts() {
// Fade out
var $anfBox = $("#anfBox"),
queue = $anfBox.queue('fx');
if (queue && queue.length === 0) {
$anfBox.fadeTo(200, 0.01, function() {
// Change products
// Fade back in
$anfBox.fadeTo(200, 1);
});
}
}
$(document).ready(function() {
// Some pre-animation stuff, like loading the products etc.
// Initialize animation timer
t = setInterval(changeProducts, 5000);
});
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) {
// ...
}