Redirecting in 10,..9,... script - javascript

Hy,
I have a 10 sec. delay page.
var t = window.setTimeout('redirect(strUrl)', 11000);
And function redirect(strUrl) just does document.location
What would be nice if i have a little message displaying at the bottom of my page, for example: Redirecting in 10 seconds...
"one second later that setTimeout fired"
...Redirecting to destiny in 9 seconds..
etc
ps. and the dots at the end going from left to right you know it. .. ...
I myselft would probably find out how to get that every second of timeout and just with jquery altered the number ...if that would be possible at all.

var timeout = 11; // in seconds
var msgContainer = $('<div />').appendTo('body'),
msg = $('<span />').appendTo(msgContainer),
dots = $('<span />').appendTo(msgContainer);
var timeoutInterval = setInterval(function() {
timeout--;
msg.html('Redirecting in ' + timeout + ' seconds');
if (timeout == 0) {
clearInterval(timeoutInterval);
redirect(strUrl);
}
}, 1000);
setInterval(function() {
if (dots.html().length == 3) {
dots.html('');
}
dots.html(function(i, oldHtml) { return oldHtml += '.' });
}, 500);
See it on jsFiddle.
If you wanted to have the second(s) thing, replace the appropriate line above with...
msg.html('Redirecting in ' + timeout + ' second' + ((timeout != 1) ? 's' : ''));
Of course, this works well with English, but probably isn't as easy with other languages.

You can do that by creating a div you position absolutely with bottom and left coordinates, and update the text in the div by looping on each second. Something like this:
function redirect(strurl) {
var seconds = 10;
var div = $("<div/>").css({
position: "absolute",
left: "0px",
bottom: "0px"
}).appendTo(document.body);
continueCountdown();
function continueCountdown() {
--seconds;
if (seconds >= 0 ) {
div.text("...Redirecting in " + seconds + " seconds...");
setTimeout(continueCountdown, 1000);
}
else {
// Redirect here
document.location = strurl;
}
}
}
Live example
Note that that will be imprecise, because the timeout will not necessarily fire in exactly one second. But it'll be close.

try this:
var count=10;
window.setTimeout(function(){redirect(url)}, 1000);
function redirect(url){
if(--count==0){
location.href=url;
return;
}
$("#DIV_TO_DISPLAY_MESSAGE").text("redirecting in " + count+" secs.");
window.setTimeout(function(){redirect(url)}, 1000);
}

Define a variable with number of secs, and in setTimeout( ... , 1000 ) call function whitch will decrease number of secs, change content of some-div/span..., and if secs = 0 redirect .

i would go for countdown-plugin. there's an example available

Related

setInterval & setTimeout executing at the wrong time

I want to change the background image using setInterval and setTimeout every x seconds but im strugling a bit. The problem is that the timer is not working as supposed to. It changes the images instantly.
let images = ['background1.jpg', 'background2.jpg','background3.jpg'];
let i = 0;
$("main").css("background-image", 'url(' + images[i] + ')');
setInterval(function(){
setTimeout( function() {
if(i == 0){
i++;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
setTimeout( function() {
if(i == 1){
i++;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
setTimeout( function() {
if(i == 2){
i = 0;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
}, 3000);
Get the main element (Or the target)
Declare the CSS background-size': 'cover for DRY (Don't Repeat Yourself) coding.
Show the first image, and increase i to show the next one in the "loop"
// The images indexes holder
let i = 0;
// Set the first image (i = 0 for now)
el.style.backgroundImage = `url(${arr[i]})`;
// increase i, to prevent showing the first image twice (for the first 6 seconds).
i++;
Finally, change the background-image every 3 sec. If reaches the last index, set to the first. And repeat...
The Code:
//var images = ['background1.jpg', 'background2.jpg','background3.jpg'];
var images = ['https://www.w3schools.com/html/img_girl.jpg',
'https://www.w3schools.com/html/pic_trulli.jpg',
'https://www.w3schools.com/html/img_chania.jpg']
var main = document.querySelector("main");
const backgroundSlider = (el, arr) => {
let i = 0;
el.style.backgroundImage = `url(${arr[i]})`;
i++;
setInterval(() => {
el.style.backgroundImage = `url(${arr[i]})`;
i++;
i == arr.length ? i = 0 : '';
}, 3000);
};
backgroundSlider(main, images);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
main {
background: center / contain no-repeat;
height: 100vh;
}
<main></main>
Your code will not work because setTimeout is async. Your 3 updates are not done like 3s,6s,9s.
The three setTimeout statements are read in stepbystep order and the functions inside them are requested(in simple terms) to be run after 3s by each one of them.
They are all done after ~3s (almost 3s) delay.
So, in the end you see the last function run which has i=0 and resets to the first image.
Edit: similar solution has been posted already. This one uses jQuery.
//This will run every 3s.
setInterval(function(){
i = (i+1)%3;
$('main').css({'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}, 3000);

function firing multiple times when scrolling fast

First of all, I'm not very advanced at code and tend to only do this part time so please excuse all terrible/ugly code! I appreciate there are already some solutions out there but I can't seem to make any of them work with my code so would really appreciate some help!
I'm using isotope grid and trying to setup an infinite scroll. I want to load 10 images at a time when the user scrolls to the bottom by taking these images from an array and appending them to a temp div.
This is working perfectly when scrolling slowly, but as soon as you scroll quickly the function seems to fire multiple times, it gets a little glitchy and loads lots of images at once.
$(window).scroll(function() {
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
var docuHeight = $(document).height();
if(scrollTop + windowHeight == docuHeight){
nextTenImages = imagesData.splice(0,10);
var content = ""
for (var i = 0; i < nextTenImages.length; i++) {
content +=
"<div class='box " + nextTenImages[i]["type"] + "'" + ">" +
"<div class='box-wrapper'>" +
"<img src='" + nextTenImages[i]["src"] + "' />" +
"</div>" +
"</div>"
};
$('body').append('<div id="temp-load"><div id="grid"></div></div>');
$('#temp-load > #grid').append(content)
$('#temp-load > #grid').children().css({
opacity: 0
});
var toAdd = $('#temp-load > #grid').html();
$container.isotope('insert', $(toAdd), function(){
$container.children().css({
opacity: 1
});
$('#temp-load').remove();
});
}
});
Make a single timeout to run the callback. This may avoid the function from executing multiple times.
var timer;
function scrollEvt() {
/* scroll actions */
}
$(window).scroll(function() {
/* clear the old timeout */
clearTimeout(timer);
/* wait until 400 ms for callback */
timer = setTimeout(scrollEvt, 400);
});
Using other ways may result in problems (like comparing (window.performance || Date).now())...
Unbind that specific scroll event till your delayed operation is completed to prevent accumulating more of the event triggers which create the duplication behaviour as in your case.
var winCached = $(window),
docCached = $(document)
var currLeng = 0;
function addContent() {
dettachScrollEvent();
setTimeout(function() { //this timeout simulates the delay from the ajax post
for (var i = currLeng; i < currLeng + 100; i++)
$('div').append(i + '<br />');
currLeng = i;
console.log("called loader!");
attachScrollEvent();
}, 500);
}
function infiNLoader() {
if (winCached.scrollTop() + winCached.height() > docCached.height() - 300) {
addContent();
//alert("near bottom! Adding more dummy content for infinite scrolling");
}
}
function attachScrollEvent() {
winCached.scroll(infiNLoader);
}
function dettachScrollEvent() {
winCached.unbind('scroll', infiNLoader);
}
addContent();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>

setInterval doesnt tigger inner script on first time run

Maybe I'm not properly understanding setInterval but I have made a kind of slideshow script, as below:
var i = 0;
setInterval(function() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
if(i == 5){
i = 0;
}
}, 4000);
This works, except for the first run - no slides will display for the first 4 seconds.
See Fiddle here: http://jsfiddle.net/vpa89snf/6/
Is there anyway I can trigger whats inside the setInterval function when it runs the first time round?
Use setTimeOut instead of setInterval for better performance, inspect the sample below:
Here is working jsFiddle.
var i = -1;
var totalSlide = $('.slide').length-1;
var slideTimer = 0;
function nextFrame() {
i == totalSlide ? i = -1 : i;
i++;
$('.slide').fadeOut(200);
$('.slide').eq(i).fadeIn(200);
slideTimer = setTimeout(nextFrame,4000);
}
$('#holder').addClass('isAni');
nextFrame();
// play / pause animation
$('#holder').click(function() {
if ( $(this).hasClass('isAni') ) {
$(this).removeClass('isAni');
clearTimeout(slideTimer);
}else{
$(this).addClass('isAni');
nextFrame();
}
});
You need to run the function and not wait for the 4 first seconds:
var i = 0;
function doSomething() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i = (i + 1) % 5;
}
$document.ready(function () {
setInterval(doSomething, 4000);
doSomething(); // run it!
});
JSFIDDLE.
This is how setInterval is executed. It runs your function after x milliseconds set as 2nd parameter.
What you have to do in order to show the first slide is to have the 1rst slide fadein like below:
var i = 0;
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
setInterval(function() {
...
}, 4000);

Convert jQuery timer and redirect to work with minutes and seconds, rather than just seconds

I have found this lightweight and excellent timer and redirect script based on jQuery, created by the 'jQuery by Example' site. The script redirects the user after a set number of seconds:
HTML:
<h1>You will be redirect to actual page after <span id="spnSeconds">10000</span> seconds.</h1>
jQuery:
$(document).ready(function () {
window.setInterval(function () {
var iTimeRemaining = $("#spnSeconds").html();
iTimeRemaining = eval(iTimeRemaining);
if (iTimeRemaining == 0) {
location.href = "http://jquerybyexample.blogspot.com/";
} else {
$("#spnSeconds").html(iTimeRemaining - 1);
}
}, 1000);
});
Here's the fiddle: http://jsfiddle.net/jquerybyexample/2WmJb/
I am trying to modify it to work with minutes and seconds - would anyone know how to do this? I've tried simply modifying the HTML to 25:00 but this doesn't seem to be working (thought it wouldn't the that simple!).
Many thanks in advance for your help...
Best to use a data attribute for the time and display whatever you want as the text:
JSFiddle: http://jsfiddle.net/2WmJb/67/
You can access the data attribute with either .data('time') or .attr('data-time')
<h1>You will be redirect to actual page after <span id="spnSeconds" data-time="1500000">25 minutes</span></h1>
$(document).ready(function () {
window.setInterval(function () {
var iTimeRemaining = $("#spnSeconds").data('time');
iTimeRemaining = ~~iTimeRemaining;
if (iTimeRemaining == 0) {
location.href = "http://jquerybyexample.blogspot.com/";
} else {
var mins = ~~(iTimeRemaining / 60000);
$("#spnSeconds").html(mins + " minutes " + ~~(iTimeRemaining / 1000 % 60) + " seconds");
$("#spnSeconds").data('time', iTimeRemaining - 1000);
}
}, 1000);
});
Also Eval is Evil in most cases. Do a simple ~~ to coerce the value to an integer value, or use parseInt.
Changes Based on comment - add a pad function for leading zeroes
JSFiddle: http://jsfiddle.net/2WmJb/69/
function pad(num, size) {
var s = "000000000" + num;
return s.substr(s.length-size);
}
$(document).ready(function () {
window.setInterval(function () {
var iTimeRemaining = $("#spnSeconds").data('time');
iTimeRemaining = ~~iTimeRemaining;
if (iTimeRemaining == 0) {
location.href = "http://jquerybyexample.blogspot.com/";
} else {
var mins = ~~(iTimeRemaining / 60000);
$("#spnSeconds").html(mins + ":" + pad(~~(iTimeRemaining / 1000 % 60),2));
$("#spnSeconds").data('time', iTimeRemaining - 1000);
}
}, 1000);
});
One final cleanup: http://jsfiddle.net/2WmJb/70/
Although not really significant when using jQuery id selectors (as they are very fast compared to say class selectors), you should reuse variables instead of repeatedly calling jQuery selectors. This example uses $span instead of $("#spnSeconds"). The $ prefix is a typical prefix for your variables that are jQuery objects (and more readable):
var $span = $("#spnSeconds");
var iTimeRemaining = $span.data('time');
iTimeRemaining = ~~iTimeRemaining;
if (iTimeRemaining == 0) {
location.href = "http://jquerybyexample.blogspot.com/";
} else {
$span.html(~~(iTimeRemaining / 60000) + ":" + pad(~~(iTimeRemaining / 1000 % 60),2));
$span.data('time', iTimeRemaining - 1000);
}

Timer not running more than once

For some reason when I run the below script for the first time, the timer doesn't activate again for a second time, any idea why?
var timer = 0;
$(document).ready(function() {
$('#search').keypress(function() {
if(timer == 0) { $('#sel').html('<iframe src="search.php?p=' + $('#search').val() + '"></iframe>'); }
timer = 1;
setTimeout('timer = 0;', 2000);
});
});
Regards
Matthew
setTimeout only runs once. You probably want setInterval.
$('#search').keypress(function() {
if(timer == 0) { setTimeout('clearTimeout(this);timer = 0;', 2000); $('#sel').html('<iframe src="search.php?p=' + $('#search').val() + '"></iframe>'); }
timer = 1;
});
Running the timer inside it fixed it well :)

Categories