How to trigger an action after setTimeout JavaScript - javascript

jsfiddle
I'm creating a function named preLoader() and I'm using setTimeout() cause I want to make it run for one time only.
When the preloader() function finish, I want to hide:
<div class="loader">
<h2 id="loading">0%</h2>
<h3 id="pleaseWait"></h3>
</div>
and show:
<div class="mainContent"></div>

Since you're using animate(), You don't really have to use both setTimeout and setInterval. Simply hide/unhide content in a complete callback of the animation.
function preLoader(){
// animating numbers
var arrayPleaseWait = ['P','L','E','A','S','E', ' ' , 'W','A','I','T','.','.','.'];
var searchReturn = '';
var current = null;
var wait = $('#pleaseWait');
$('body').css({
'backgroundColor':'#E2F7FA'
});
$('.mainContent').hide();
$('#loading').animate({
someValue: 100
},{
duration: 10000,
easing:'swing',
step: function() {
var l = Math.round(Math.round(this.someValue) * (arrayPleaseWait.length-1) / 100) || 0;
if(current != l){
searchReturn = searchReturn + arrayPleaseWait[l];
wait.text(searchReturn + '|');
current = l;
}
$(this).text(Math.round(this.someValue) + '%');
},
complete : function(){
$('.loader').hide();
$('.mainContent').show();
}
});
}
preLoader();
JSfiddle demo

this is the HTML code:
<div class="loader">
<h2 id="loading">0%</h2>
<h3 id="pleaseWait">pleaswait</h3>
</div>
<div class="mainContent" hidden="true">ok</div>
JavaScript:
var executed = false;
setTimeout(function() {
if(!executed) {//the same of if(executed == false)
var loader = document.getElementsByClassName('loader')[0];
var mainContent = document.getElementsByClassName('mainContent')[0]
loader.hidden = "true";//hide the loader
mainContent.removeAttribute("hidden");//show the mainContent
executed = true;
}
}, 1000);

Related

Typing effect for list of strings. Need help fixing order of events

I need the following code to type/untype each string, one at a time, in the order they are listed. Currently, it executes, but the i++ is firing too many times within the loop and breaking the order of events. Please help correct the iterations so that any amount of strings may be typed/untyped in order.
<div class="flex-container">
<h1>Innovative Solutions
<br>for
<span id="str"></span>
</h1>
<hr>
<p>This is filler content. The text in this area will be replaced when copy for the site becomes available. This is filler content. The text in this area will be replaced when copy for the site becomes available.</p>
Learn More
</div>
$(function() {
var speed = 200;
var speed2 = 50;
var str = document.getElementById('str');
var i = 0;
var isRemoving = false;
var messages = [
"Cyber Security...",
"Vulnerability Assessments...",
"Program Management...",
"Compliance Management..."
]
function action() {
console.log('Action')
if (isRemoving) {
if (str.innerText.length > 0) {
str.innerText = str.innerText.substr(0, str.innerHTML.length - 1);
setTimeout( action, speed2 );
return;
}
isRemoving = false;
i++;
if (i === messages.length) {
i = 0;
}
setTimeout( action, 500 );
return;
}
var message = messages[i];
str.innerText = message.substr(0, str.innerHTML.length + 1);
if (str.innerText.length === message.length) {
setTimeout(function() {
isRemoving = true;
console.log(isRemoving)
}, 2000)
}
setTimeout( action, isRemoving ? speed2 : speed );
}
setTimeout( action, speed ) ;
})
I would aim to only have one occurrence of setTimeout in your code. Make all the rest dynamic, and pass the state to each next call of action (use bind for this).
Here is how that would look:
var str = document.getElementById('str');
var messages = [
"Cyber Security...",
"Vulnerability Assessments...",
"Program Management...",
"Compliance Management..."
]
function action(idx, len, dir) {
str.textContent = messages[idx].slice(0, len);
if (len % messages[idx].length == 0) dir = -dir; // Change direction
setTimeout(
action.bind(null, (idx+(len==0)) % messages.length, len+dir, dir),
len == messages[idx].length ? 2000 : dir < 0 ? 50 : 200 // Delay
);
}
action(0, 1, 1); // Not really useful to have setTimeout here. Just call it.
<div class="flex-container">
<h1>Innovative Solutions
<br>for
<span id="str"></span>
</h1>
<hr>
<p>This is filler content.</p>
</div>
If you don't want to rework your whole code, you can call your i++; just when the message is fully typed (str.innerText.length === message.length)
$(function() {
var speed = 200;
var speed2 = 50;
var str = document.getElementById('str');
var i = 0;
var isRemoving = false;
var messages = [
"Cyber Security...",
"Vulnerability Assessments...",
"Program Management...",
"Compliance Management..."
]
function action() {
console.log('Action')
if (isRemoving) {
if (str.innerText.length > 0) {
str.innerText = str.innerText.substr(0, str.innerHTML.length - 1);
setTimeout(action, speed2);
return;
}
isRemoving = false;
setTimeout(function() {
action();
}, 500);
return;
} else {
var message = messages[i];
console.log(i);
str.innerText = message.substr(0, str.innerHTML.length + 1);
if (str.innerText.length === message.length) {
i++;
if (i === messages.length) {
i = 0;
}
setTimeout(function() {
isRemoving = true;
setTimeout(action, isRemoving ? speed2 : speed);
}, 2000)
} else {
setTimeout(action, isRemoving ? speed2 : speed);
}
}
}
setTimeout(action, speed);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex-container">
<h1>Innovative Solutions
<br>for
<span id="str"></span>
</h1>
<hr>
<p>This is filler content. The text in this area will be replaced when copy for the site becomes available. This is filler content. The text in this area will be replaced when copy for the site becomes available.</p>
Learn More
</div>
$(function() {
var speed = 200;
var speed2 = 50;
var str = document.getElementById('str');
var index =0;
var isRemoving = false;
var messages = [
"Cyber Security...",
"Vulnerability Assessments...",
"Program Management...",
"Compliance Management..."
]
function getIndex(index1){
if(index1===messages.length){
return(0)
}
else{
return(index1);
}
}
function action(){
if(isRemoving){
str.innerText = str.innerText.substr(0,str.innerHTML.length - 1);
if(str.innerHTML.length===0) {
index=getIndex(index+1);
isRemoving=false;
}
setTimeout( action, speed2 );
}
else{
str.innerText = messages[index].substr(0, str.innerHTML.length + 1);
if(str.innerHTML.length===messages[index].length){
isRemoving=true;
}
setTimeout( action, speed );
}
}
setTimeout( action, speed ) ;
});
<div class="flex-container">
<h1>Innovative Solutions
<br>for
<span id="str"></span>
</h1>
<hr>
<p>This is filler content. The text in this area will be replaced when copy for the site becomes available. This is filler content. The text in this area will be replaced when copy for the site becomes available.</p>
Learn More
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

On mouseout stop setInterval

I'm trying to create a simple image rotator on hover effect. It working properly on mouse hover, but doesn't work when mouse out method.
var imgFlip = $("img").data( "flip" );
var imgOriginal = $("img").data( "original" );
var images = imgFlip.split(/,|, |;|; /);
var index = 0;
function rotateImage()
{
$('.img-rotator').fadeOut('fast', function()
{
$(this).attr('src', images[index]);
$(this).fadeIn('fast', function()
{
if (index == images.length-1)
{
index = 0;
}
else
{
index++;
}
});
});
}
$(document).ready(function()
{
$('.img-rotator')
.mouseover(function () {
var refreshIntervalId = setInterval (rotateImage, 1000);
})
.mouseout(function () {
$(this).attr('src', imgOriginal);
})
});
Jsfiddle example here - https://jsfiddle.net/wbz35L68/15/
Thank you for any advice
You need to clear the setInterval on mouseout. I also reworked some of your code to clean things up and cache refs. You should also use mouseenter and mouseleave for this.
$(document).ready(function(){
// cache selector
var rotator = $('.img-rotator'),
// grab all data
data = rotator.data(),
// ref flip
imgFlip = data.flip,
// ref original
imgOriginal = data.original,
// get image urls
images = imgFlip.split(/,|, |;|; /),
// start index
index = 0,
// ref interval
refreshIntervalId = null;
function rotateImage(){
rotator.fadeOut('fast', function(){
$(this)
.attr('src', images[index])
.fadeIn('fast', function(){
var last = index === images.length - 1;
index = last ? 0 : index + 1;
});
});
}
rotator
.mouseenter(function(){
refreshIntervalId = setInterval(rotateImage, 1000);
})
.mouseleave(function(){
// clear interval and set null
clearInterval(refreshIntervalId) && (refreshIntervalId = null);
$(this).attr('src', imgOriginal);
})
});
.container {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col">
<img class="img-rotator" data-flip="http://www.snorkl.tv/dev/loaderMax/images/bird.png, http://www.snorkl.tv/dev/loaderMax/images/whale.png" data-original="http://www.snorkl.tv/dev/loaderMax/images/crab.png" src="http://www.snorkl.tv/dev/loaderMax/images/crab.png" width="320" height="200"/>
</div>
</div>
</div>

Selecting random div for auto fade in and fade out

Currently, this code is auto fade in and fade out div by selecting the div element the way they were arranged (consecutive order). What I want to do now is to make the selector in random, I want to fade in a random div and after fading it out it will pick another random div and infinite loop the process. Since I'm new in jQuery and so confused, I also want to know your opinion on how to put this such process on a If Else statement in the easiest way. Like for example, I will get the value of a number
int num = 1;
If(num == 1){
<!-- Do the process-->
}
Else {
<!-- Do another process by selecting from another set of divs-->
}
Here is the code:
jQuery.fn.nextOrFirst = function (selector) {
var next = this.next(selector);
return (next.length) ? next : this.prevAll(selector).last();
}
$(document).ready(function () {
$('div.mb').fadeOut(500);
var fadeInTime = 1000;
var intervaltime = 3000;
setTimeout(function () {
fadeMe($('div.mb').first());
}, intervaltime);
function fadeMe(div) {
div.fadeIn(fadeInTime, function () {
div.fadeOut(fadeInTime);
setTimeout(function () {
fadeMe(div.nextOrFirst());
}, intervaltime);
});
}
});
Divs:
<div class="boxes">
<div class="mb one">1-------------one</div>
<div class="mb two">2-------------two</div>
<div class="mb three">3-------------three</div>
</div>
Not sure if this is exactly what you want but can be modified:
var mb = $('.mb'),
mbl = mb.length;
mb.hide();
rand();
function rand(){
var r = getRand(0, mbl);
mb.eq(r).fadeIn('slow', function(){
$(this).fadeOut('slow', function(){
setTimeout(rand, 200);
});
});
}
function getRand(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
Try changing the nextOrFirst function to something like:
jQuery.fn.nextOrFirst = function (selector) {
var xCount = selector.size();
return Math.floor(Math.random() * xCount ) + 1;
}
Instead of getting the next of first div, this gets a count of all of the divs,
and pics a random number between 1 and X(the number of divs with your selector)
Try something like this,Hope it helps
var c=$(".boxes div");
setInterval(function(){
$.each(c,function(a,z){
$("div[class='"+(z.className)+"'").fadeIn();
});
var item = c[Math.floor(Math.random()*c.length)];
var u=item.className;
$("."+u).fadeOut();
$("div[class='"+u+"'").fadeOut(1000);
}, 3000);
EDIT:
var c=$(".boxes div");
setInterval(function(){
$.each(c,function(a,z){
$("div[class='"+(z.className)+"'").hide();
});
var item = c[Math.floor(Math.random()*c.length)];
var u=item.className;
$("."+u).fadeOut();
$("div[class='"+u+"'").show().fadeIn(1000);
}, 2000);
FIDDLE LINK: https://jsfiddle.net/bv0jj4wp/29/

JQuery Auto Click

I have a problem, I have 3 button lets say it's called #pos1, #pos2 and #pos3.
I want to makes it automatically click #pos1 button in 2 seconds, after that click the #pos2 after another 2 seconds, and #pos3 after another 2 seconds,
after that back to the #pos1 in another 2 seconds and so on via jQuery.
HTML
<button id="pos1">Pos1</button>
<button id="pos2">Pos2</button>
<button id="pos3">Pos3</button>
Anyone can help me please?
Try
$(function() {
var timeout;
var count = $('button[id^=pos]').length;
$('button[id^=pos]').click(function() {
var $this = $(this);
var id = $this.attr('id');
var next = parseInt(id.substring(4), 10) + 1;
if( next >= count ){
next = 1
}
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
$('#pos' + next).trigger('click');
}, 2000);
})
timeout = setTimeout(function() {
$('#pos1').trigger('click');
}, 2000);
})
var posArray = ["#pos1", "#pos2", "#pos3"];
var counter = 0;
setInterval(function() {
$(posArray[counter]).triggerHandler('click');
counter = ((counter<2) ? counter+1 : 0);
}, 2000);
That should do the trick, though you did not mention when you want it to stop running.
Well I don't know what you already have but technically it could be done via triggerHandler()
var currentPos = 1,
posCount = 3;
autoclick = function() {
$('#pos'+currentPos).triggerHandler('click');
currentPos++;
if(currentPos > posCount) { currentPos = 1; }
};
window.setInterval(autoclick,2000);
If I have understood you question right, you need to perform click in a continuous loop in the order pos1>pos2>pos3>pos1>pos2 and so on. If this is what you want, you can use jQuery window.setTimeout for this. Code will be something like this:
window.setTimeout(performClick, 2000);
var nextClick = 1;
function performClick() {
if(nextClick == 1)
{
$("#pos1").trigger("click");
nextClick = 2;
}
else if(nextClick==2)
{
$("#pos2").trigger("click");
nextClick = 3;
}
else if(nextClick == 3)
{
$("#pos3").trigger("click");
nextClick = 1;
}
window.setTimeout(performClick, 2000);
}
This is quite buggy but will solve your problem.
using setInterval()
Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function.
var tempArray = ["pos1", "pos2", "pos3"]; //create an array to loop through
var arrayCounter = 0;
setInterval(function() {
$('#' + tempArray[arrayCounter ]).trigger('click');
arrayCounter = arrayCounter <2 ? arrayCounter +1 : 0;
}, 2000);
fiddle here
check your console for fiddle example

jquery stop image rotation on mouseover, start on mouseout / hover

I have built a jQuery rotator to rotate through 3 divs and loop them. I would like to add the functionality on mouse over to "freeze" the current div and then start again on mouse out.
I've thought about setting a variable to false at the start of the function and setting it true when it's on it's current frame but I've got my self a bit confused.
I've also tried to use the hover function but when using the in and out handlers, I'm confused as to how to stop, restart the animation.
function ImageRotate() {
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).delay(4500).animate({'top' : '330px'}, 3000);
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).delay(4500).animate({'top' : '0px'}, 3000);
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).delay(4500).css('top' , '-330px');
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500)};
Any help would be greatly appreciated!!
Thanks, Matt
If you were to add this code:
var timerId = null;
function startRotation() {
if (timerId) {
return;
}
timerId = setInterval('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500);
}
function stopRotation() {
if (!timerId) {
return;
}
clearInterval(timerId);
timerId = null;
}
and replace the last line of your code block with a simple call to startRotation();, then you could call stopRotation and startRotation when the mouse hovers over/leaves your element:
$('your-element-selector').hover(stopRotation, startRotation);
It's not clear what you are trying to do with the three divs without seeing the HTML and more code, so I think a basic example might help you better (demo).
HTML
<div class="test">image: <span></span></div>
Script
$(document).ready(function(){
var indx = 0, loop, numberOfFeatures = 5;
function imageRotate(){
indx++;
if (indx > numberOfFeatures) { indx = 1; }
$('.test span').text(indx);
loop = setTimeout( imageRotate , 1000 );
}
imageRotate();
$('.test').hover(function(){
clearTimeout(loop);
}, function(){
imageRotate();
});
})
changed things up a little bit, here is how I ended up doing it. `
var animRun = false;
var rotateHover = false;
function startRotation() {
rotateHover = false;
ImageRotate();
}
function stopRotation() {
rotateHover = true;
clearTimeout();
}
function ImageRotate() {
if (rotateHover == false){
animRun = true;
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).animate({'top' : '330px'}, featureDuration, function(){animRun = false;});
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).animate({'top' : '0px'}, featureDuration); /* rotate slide 2 into main frame */
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).css('top' , '-330px'); /*bring slide 3 to the top*/
//startRotation();
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; if (rotateHover == false){ImageRotate2()};', featureDelay);
};
};

Categories

Resources