Execute function IF another function is complete NOT when - javascript

I am having trouble creating a slider that pauses on hover, because I execute the animation function again on mouse off, if I flick the mouse over it rapidly (thereby calling the function multiple times) it starts to play up, I would like it so that the function is only called if the other function is complete, otherwise it does not call at all (to avoid queue build up and messy animations)
What's the easiest/best way to do this?
$(document).ready(function() {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
$('.slider_container').hover(function() {
//Mouse on
n = 0;
$('.slider').stop(true, false);
}, function() {
//Mouse off
n = 1;
if (fnct == 0) sliderLoop();
});
//Called in Slide Loop
function animateSlider() {
$('.slider').delay(3000).animate({ marginLeft: -(slide_width * i) }, function() {
i++;
sliderLoop();
});
}
var i = 0;
var fnct = 0
//Called in Doc Load
function sliderLoop() {
fnct = 1
if(n == 1) {
if (i < number_of_slides) {
animateSlider();
}
else
{
i = 0;
sliderLoop();
}
}
fnct = 0
}
sliderLoop();
});
The slider works fine normally, but if I quickly move my mouse on and off it, then the slider starts jolting back and forth rapidly...been trying to come up with a solution for this for hours now..

Here's what fixed it, works a charm!
$(document).ready(function() {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,3000);
});
var marginSize = i = 1;
var fnctcmp = 0;
//Called in Doc Load
function sliderLoop() {
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize });
}
t = setInterval(sliderLoop,3000);
});

Related

How to create a screensaver in javascript

I want to create a screensaver in JavaScript but I don't know how can I set the time between the images,.
I have an Ajax call and I see if the time is, for example, 2s or 90s, but I don't know how to set that time between images, this is my code:
var cont = 0;
var time = 1000
setInterval(function() {
console.log(tiempo);
if(cont == imagenes.length){
return cont = 0;
}else{
var imagen = imagenes[cont].imagen;
$('#imgZona').attr('src', imagen);
var time = imagenes[cont].tiempoVisible;
finalTime = Number(time);
}
cont++;
}, Number(finalTime ));
but the time between images is always the same, 1000, how can I change it for the time that I receive in the Ajax call? Which is imagenes[cont].tiempoVisible
I cannot comment as I don't have enough reputation, but take a look at this fiddle
https://jsfiddle.net/kidino/4mbpR/
var mousetimeout;
var screensaver_active = false;
var idletime = 5;
function show_screensaver(){
$('#screensaver').fadeIn();
screensaver_active = true;
screensaver_animation();
}
function stop_screensaver(){
$('#screensaver').fadeOut();
screensaver_active = false;
}
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
$(document).mousemove(function(){
clearTimeout(mousetimeout);
if (screensaver_active) {
stop_screensaver();
}
mousetimeout = setTimeout(function(){
show_screensaver();
}, 1000 * idletime); // 5 secs
});
function screensaver_animation(){
if (screensaver_active) {
$('#screensaver').animate(
{backgroundColor: getRandomColor()},
400,
screensaver_animation);
}
}
It will change background-color on idle mouse for 5 seconds, you can replace the code to change image, instead of background color.
Control set every timeout on each iteration.
var cont = 0;
var time = 1000
function next () {
console.log(tiempo);
if(cont == imagenes.length){
cont = 0;
}
var imagen = imagenes[cont].imagen;
$('#imgZona').attr('src', imagen);
cont++;
setTimeout(next, Number(imagenes[cont].tiempoVisible));
}
setTimeout(next, Number(initialTime));
Also I fixed a frindge condition.

Pause autonomous function if user interacts?

I'm trying to make a carousel that runs automatically, but if a user interacts with the controls I want the carousel to reset its timer.
What ive built works to an extent, but if you interact with the control-dot the timer isnt reset so it throws some funny results...
Here's my JS
/* Js for carousel */
$('.steps__step-1').addClass('active');
$(function() {
var lis = $('.step'),
currentHighlight = 0;
N = 5; // Duration in seconds
setInterval(function() {
currentHighlight = (currentHighlight + 1) % lis.length;
lis.removeClass('active').eq(currentHighlight).addClass('active');
}, N * 1000);
});
$('.control-dot').on('click', function(e) {
e.preventDefault();
$('.active').removeClass('active');
var itemNo = $(this).index() - 1;
$('.step').eq(itemNo).addClass('active');
});
http://jsfiddle.net/tnzLha3o/1/
You should store interval id in a variable (let intervalId = setInterval(...)) and then use it to restart it.
Here is your updated fiddle: http://jsfiddle.net/gudzdanil/uzoydp6a/2/
So that your code will look like:
var duration = 5;
var lis = $('.step'),
currentHighlight = 0;
var intervalId = null;
$(function() {
$('.steps__step-1').addClass('active');
runCarousel();
});
$('.control-dot').on('click', function(e) {
e.preventDefault();
$('.active').removeClass('active');
var itemNo = $(this).index() - 1;
$('.step').eq(itemNo).addClass('active');
rerunCarousel();
});
function rerunCarousel() {
if(intervalId) clearInterval(intervalId);
intervalId = null;
runCarousel();
}
function runCarousel() {
intervalId = setInterval(function() {
currentHighlight = (currentHighlight + 1) % lis.length;
lis.removeClass('active').eq(currentHighlight).addClass('active');
}, N * 1000)
}
Add a variable to stop it.
var stop = false
$('.steps__step-1').addClass('active');
$(function() {
var lis = $('.step'),
currentHighlight = 0;
N = 5; // Duration in seconds
setInterval(function() {
if (!stop) {
currentHighlight = (currentHighlight + 1) % lis.length;
lis.removeClass('active').eq(currentHighlight).addClass('active');
}
}, N * 1000);
});
$('.control-dot').on('click', function(e){
e.preventDefault();
$('.active').removeClass('active');
var itemNo = $(this).index() - 1;
$('.step').eq(itemNo).addClass('active');
stop = !stop
});
http://jsfiddle.net/quvgxz63/

get interval ID from else statement when set in IF

I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});

Jquery = setInterval code works in Firefox but not in Chrome

The code (from an old plugin that I am trying to make responsive) slides a set of images across every n seconds. It uses setInterval code as below, and works well on Firefox. On Chrome it runs once only, and debugging indicates that the second setInteral function is just not called. Please help as its diving me mad. Running example at http://lelal.com/test/site10/index.html (sorry about the load time)
play = setInterval(function() {
if (!busy) {
busy = true;
updateCurrent(settings.direction);
slide();
}
}, settings.speed);
The complete plugin code is below (sorry its long)
/*
* jQuery Queue Slider v1.0
* http://danielkorte.com
*
* Free to use and abuse under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
(function($){
var QueueSlider = function(element, options) {
var play = false,
busy = false,
current = 2,
previous = 2,
widths = [],
slider = $(element),
queue = $('ul.queue', slider),
numImages = $('img', queue).size(),
viewportWidth = slider.width(),
settings = $.extend({}, $.fn.queueSlider.defaults, options);
$(window).resize(function(){
if(busy !== false)
clearTimeout(busy);
busy = setTimeout(resizewindow, 200); //200 is time in miliseconds
});
function resizewindow() {
viewportWidth = slider.width();
if (settings.scale > 0) {
slider.css('height',viewportWidth * settings.scale);
computeQueueWidth();
}
queue.css('left', -getQueuePosition());
busy = false;
}
function requeue() {
$('li', queue).each(function(key, value) {
$(this).attr('class', 'slide-' + (key+1));
});
}
function updateCurrent(dir) {
current += dir;
if (current < 1) {
current = numImages;
} else if (current > numImages) {
current = 1;
}
}
function getQueuePosition() {
var i = 0, index = current-1,
queuePosition = (viewportWidth - widths[index]) / -2;
for (i = 0; i < index; i++) { queuePosition += widths[i]; }
return queuePosition;
}
function computeQueueWidth() {
var queueWidth = 0;
// factor = slider.height() / settings.imageheight;
// settings.imageheight = settings.imageheight * factor;
// Get the image widths and set the queue width to their combined value.
$('li', queue).each(function(key, value) {
var slideimg = $("img", this),
slide = $(this),
// width = slide.width() * factor,
width = slideimg.width();
slide.css('width', width+'px');
queueWidth += widths[key] = width;
});
queue.css('width', queueWidth + 500);
}
function slide() {
var animationSettings = {
duration: settings.transitionSpeed,
queue: false
};
// Emulate an infinte loop:
// Bring the first image to the end.
if (current === numImages) {
var firstImage = $('li.slide-1', queue);
widths.push(widths.shift());
queue.css('left', queue.position().left + firstImage.width()).append(firstImage);
requeue();
current--; previous--;
}
// Bring the last image to the beginning.
else if (current === 1) {
var lastImage = $('li:last-child', queue);
widths.unshift(widths.pop());
queue.css('left', queue.position().left + -lastImage.width()).prepend(lastImage);
requeue();
current = 2; previous = 3;
}
// Fade in the current and out the previous images.
if (settings.fade !== -1) {
$('li.slide-'+current, queue).animate({opacity: 1}, animationSettings);
$('li.slide-'+previous, queue).animate({opacity: settings.fade}, animationSettings);
}
// Animate the queue.
animationSettings.complete = function() { busy = false; };
queue.animate({ left: -getQueuePosition() }, animationSettings);
previous = current;
}
//
// Setup the QueueSlider!
//
if (numImages > 2) {
// Move the last slide to the beginning of the queue so there is an image
// on both sides of the current image.
if (settings.scale > 0) {
slider.css('height',viewportWidth * settings.scale);
}
computeQueueWidth();
widths.unshift(widths.pop());
queue.css('left', -getQueuePosition()).prepend($('li:last-child', queue));
requeue();
// Fade out the images we aren't viewing.
if (settings.fade !== -1) { $('li', queue).not('.slide-2').css('opacity', settings.fade); }
// Include the buttons if enabled and assign a click event to them.
if (settings.buttons) {
slider.append('<button class="previous" rel="-1">' + settings.previous + '</button><button class="next" rel="1">' + settings.next + '</button>');
$('button', slider).click(function() {
if (!busy) {
busy = true;
updateCurrent(parseInt($(this).attr('rel'), 10));
clearInterval(play);
slide();
}
return false;
});
}
// Start the slideshow if it is enabled.
if (settings.speed !== 0) {
play = setInterval(function() {
if (!busy) {
busy = true;
updateCurrent(settings.direction);
slide();
}
}, settings.speed);
}
}
else {
// There isn't enough images for the QueueSlider!
// Let's disable the required CSS and show all one or two images ;)
slider.removeClass('queueslider');
}
};
$.fn.queueSlider = function(options) {
return this.each(function(key, value) {
var element = $(this);
// Return early if this element already has a plugin instance.
if (element.data('queueslider')) { return element.data('queueslider'); }
// Pass options to plugin constructor.
var queueslider = new QueueSlider(this, options);
// Store plugin object in this element's data.
element.data('queueslider', queueslider);
});
};
$.fn.queueSlider.defaults = {
scale: 0,
imageheight: 500,
fade: 0.3, // Opacity of images not being viewed, use -1 to disable
transitionSpeed: 700, // in milliseconds, speed for fade and slide motion
speed: 7000, // in milliseconds, use 0 to disable slideshow
direction: 1, // 1 for images to slide to the left, -1 to silde to the right during slideshow
buttons: true, // Display Previous/Next buttons
previous: 'Previous', // Previous button text
next: 'Next' // Next button text
};
}(jQuery));
Have a look here:
http://www.w3schools.com/jsref/met_win_setinterval.asp
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
Looks like you're calling clearInterval after the first usage of play, which makes it stop working.

pausing function on hover

I have a function written in javascript that allows me to scroll through an array of images iterated at a certain interval, now I would like to add some more functionality to it by pausing the rotation when I hover over any of the images in the array.
Javascript
(function() {
var rotator = document.getElementById('bigImage');
var imageDir = '../images/headers/';
var delayInSeconds = 5;
var images = ['ImageOne.png', 'ImageTwo.png', 'ImageThree.png', 'ImageFour.png',
'ImageFive.png',
'ImageSix.png'];
var num = 0;
var changeImage = function() {
var len = images.length;
bigImage.src = imageDir + images[num++];
if (num == len) {
num = 0;
}
};
setInterval(changeImage, delayInSeconds * 1000);
})();​
You could store the id returned from setInterval, and pass it to clearInterval when the image is hovered over.
So, on mouse over, you clear, and on mouse out you set it going again.
Hope that helps!
Use jQuery:
var rotationRunning = true;
var changeImage = function() {
if (rotationRunning) {
var len = images.length;
rotator.src = imageDir + images[num++];
if (num == len)
num = 0;
}
}
};
$(rotator).hover(
function() { rotationRunning = false; },
function() { rotationRunning = true; }
);

Categories

Resources