use of "setTimeout" to repeat function causes browser to display "Loading..." message - javascript

I have this banner rotator which is working fine except for one problem...
This rotator here first goes through the function and when it reaches the "setTimeout" statement it triggers the "cycle" function again and again.
You guys probably know that in Firefox there is a status-bar in the bottom-left corner, which says "loading" or "waiting for domain.com..." etc etc.
The problem is this; When you enter the website in Firefox, the status bar says "Loaded" and dissappears. Then after 8 seconds (the setTimeout delay) the status bar shows again and displays something like "Getting data from domain.com...". And it doesn't go away.
This message is most likely caused by the setTimeout code, which triggers the function cycle over and over again.
Is there any way of "solving" this?
This probably happens in other browsers also, but so far I have only tested it in FF.
function ban_rot(){
//First preload images
// counter
var i = 0;
// create object
imageObj = new Image();
// set image list
images = new Array();
images[0] = "../Graphics/adv/1.gif"
images[1] = "../Graphics/adv/2.jpg"
// start preloading
for (i = 0; i <= images.length; i++) {
imageObj.src = images[i];
}
///////////////////////
var links = new Array("http://www.link1.com", "http://www.link2.se");
var alts = new Array("alt1", "alt2");
var titles = new Array("title1", "title2");
var counter = 0;
var banner_div = document.getElementById("ban_rot");
cycle();
function cycle() {
if (counter == links.length) {
counter = 0;
}
else if (counter < links.length) {
banner_div.innerHTML = '<img src=\"' + images[counter] + '\" border=\"1px\" style=\"border-color:#000;\" alt=\"' + alts[counter] + '\" title=\"' + titles[counter] + '\">';
//increase counter
counter++;
}
setTimeout(cycle, 8000);
} //end cycle function
} //end ban_rot function

The browser is showing a loading indicator because you're making it load a new image.

Related

Slideshow error "RangeError: Maximum call stack size exceeded

I am trying to add this image slideshow into my website, However keeping running into a MAximum call stack size exceeded. The slider runs through the images not in the time interval set and then the error occurs
var i = 0; // Start Point
var images = []; // Images Array
var time = 3000; // Time Between Switch
// Image List
images[0] = "http://lorempixel.com/400/200/animals";
images[1] = "http://lorempixel.com/400/200/sports";
images[2] = "http://lorempixel.com/400/200/food";
images[3] = "http://lorempixel.com/400/200/people";
// Change Image
function changeImg(){
document.slide.src = images[i];
// Check If Index Is Under Max
if(i < images.length - 1){
// Add 1 to Index
i++;
} else {
// Reset Back To O
i = 0;
}
// Run function every x seconds
setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
I am posting this as an answer to have a minimal, complete and verifiable example (mcve) to make sure that the slider is not the culpritd, the code will not give that error.
Here is current syntax - if that still gives an error then there is certainly something else wrong
let i = 0, img;
const images = ["https://via.placeholder.com/150/0000FF/808080?text=Image1",
"https://via.placeholder.com/150/FF0000/FFFFFF?text=Image2",
"https://via.placeholder.com/150/FFFF00/000000?text=Image3",
"https://via.placeholder.com/150/000000/FFFFFF/?text=Image4"
];
const changeImg = function() {
slide.src = images[i];
i++;
if (i >= images.length) i = 0;
}
window.addEventListener("load", function() {
img = document.getElementById("slide");
changeImg();
setInterval(changeImg, 2000);
})
<img id="slide" />

Changing pictures with changing opacity

I have built a code which change pictures every 5 second using setinterval() and everytime when a picture is changes, it will show up with it's opacity growing from 0 to 1, using setinterval() as well.
It all works excellently, but there is a single problem which I can find the way to fix it. The problem is that after I start the page, if I move to a differend tab, if I come back in a minute, it all goes craze and the opacity is growing too fast and more then once before a picture is changed.
Here is the code:
var images = [], x = 0, t = 0, timerid, s = 0;
images[0] = "Images/" + location.pathname.substring(1, location.pathname.length - 5) + "2.jpg";
images[1] = "Images/" + location.pathname.substring(1, location.pathname.length - 5) + ".jpg";
function ChangeOpacity() {
img = document.getElementById("img");
s += 0.003;
t = s.toString();
img.style.opacity = t;
if (img.style.opacity>=1) {
s = 0;
clearInterval(timerid);
}
}
function SwitchImage() {
img = document.getElementById("img");
img.src = images[x];
img.style.opacity = 0;
timerid = setInterval('ChangeOpacity()', 1);
x++;
if (x >= images.length)
x = 0;
}
function StartFun() {
setInterval('SwitchImage()', 5000);
}
You could add a window.onblur and window.onfocus function. Each time the tab loses focus (onblur) you could clear the interval and restart it when the tab gets focused again (onfocus).
More about focus on tabs
Edit:
Restarting the interval is not necessary in all cases.

Does alert('some message') can make an impact in a callback function - Javascript

I had written a callback function to capture the snapshot of running video using html5 video control and canvas.
I used a for loop to iterate and call the same callback function take the burst capture. If i add alert('') in the callback , the video in the background rerendering when alert message display, the burst snap shot works fine as taking diff photos(frames/images of the running video). But when I removed the alert('') , the video does not run in the background and the bursted images are the same instead of different.
The code
for (var i = 0; i < burstcount; i++) {
var wcam = Webcam;
wcam.burst_snap(function (dataurl, id) {
var arrayindex = passedName + "_" + id;
imgid = imgid + i;
alert(dataurl);
burstcapturedata[arrayindex] = dataurl;
}, i);
var j = 0;
while (j < 10000000000) {
j++;
}
}
DisplayBurstedImages();
}
Yes, actually. Alert holds next execution of code. If your code works with alert it means that you require delay.
Try setTimeout or put the code in the correct place where everything is getting loaded.
I guess it needs time for binding video. you can use setTimeout function for delay.
var delay =100;
setTimeout(function () {/*your function*/ }, delay);
delay = delay + 300;
Your code needs to look something like this:
var wcam = Webcam;
var cnt = 0;
wcam.burst_snap(function(dataurl, id) {
var arrayindex = passedName + "_" + id; //you do not have an array if this is the key
imgid = imgid + cnt; //no clue what this is for
cnt++;
burstcapturedata[arrayindex] = dataurl;
if (cnt===burstcount) {
DisplayBurstedImages();
}
}, 100); //no clue what that value is supposed to be

Javascript - loading images

I have a javascript which uses many images, and I want to load them all before the user starts clicking around. The images are a little bit big, so it takes a while. Here's my code:
startTest();
function preloadImages() {
console.log("preload images");
for(var i = 1; i <= 132; i++) {
var img = new Image();
images[i-1] = "images/"+i+".png";
img.src = images[i-1];
if(i == 132) {
img.load = doneLoading();
}
}
}
function doneLoading() {
console.log("done loading");
document.getElementById("laading").style.display = "none";
console.log("loading gone");
showReady();
}
function startTest() {
console.log("start test");
trialCount = 0;
document.getElementById("laading").style.display = "block";
preloadImages();
var hammertime = Hammer(document.body).on("touch", function(event) {
registerTouch(event);
});
startTestTime = +new Date();
console.log("end start test");
}
As you can see, startTest() is first called, which calls preload images. Here's the issue:
When I load the page in the browser, the javascript console indicates that "done loading" has been printed, however the spinny wheel on the tab in the browser shows that the webpage is still loading...
What's going on here? How can I figure out once all my images are done loading?
You need to check on each image load that the image is the last one to load. Check using a count variable (loaded).
function preloadImages() {
var loaded = 0;
for(var i = 0; i <= 132; i++) {
var img = new Image();
images.push("images/"+(i+1)+".png");
img.src = images[i];
img.onload = function(){
loaded++;
if(!(loaded < 132)){
// all images have loaded
doneLoading();
}
}
}
}
In order to do a pre-loading, you will have to keep checking the complete status for each image that is being downloaded. Since, you can't know beforehand how much time it will take for each image to download (depending on latency or size), you will have to implement a timer which will keep polling the complete status on each image.
Here is one possible algorithm:
var timer = null,
numImages = 132,
allImages = new Array;
function preLoadImages() {
document.getElementById('loadcaption').innerHTML = 'Loading images... ';
for (var i = 0; i < numImages; i++) {
var tmp = "images/" + i + ".png";
allImages[i] = new Image();
allImages[i].onLoad = imgOnLoad(tmp);
allImages[i].src = tmp;
}
timer = window.setInterval('checkLoadComplete()', 250);
}
function imgOnLoad(imgName) { window.status = 'Loading image... ' + imgName; }
function checkLoadComplete() {
for (var i = 0; i < allImages.length; i++) {
if (!allImages[i].complete) {
imgOnLoad(allImages[i].src);
document.getElementById('loadcaption').innerHTML = 'Loading images... ' + Math.round((i/allImages.length)*100,0) + ' %';
return;
}
}
window.clearInterval(timer);
document.getElementById('loadcaption').innerHTML = 'Completed.';
window.status = '';
}
Where loadcaption is a simple HTML element to show progress. (You can also use an animated gif for loading animation).
The idea is to keep checking the complete status on each image by calling checkLoadComplete by a timer. Once all images are (load) complete, the for loop exits and the timer is cleared.
You start the pre-loading process by calling preLoadImages(); function.

Javascript - Show 18 images and then stop

What I'm trying to do is to change a background image 17 times, and then stop. When the user opens a new page, the same thing should happen, load 17 images and stop. The thing is, I don't know much about javascipt (I will learn I promise.) I found a script, it works, but I geuss I have to add a break. I tried but didn't succeed. Here's the code:
var imgArr = new Array(
// relative paths of images
'images/bgshow/1.jpg',
'images/bgshow/2.jpg',
'images/bgshow/3.jpg',
'images/bgshow/4.jpg',
'images/bgshow/5.jpg',
'images/bgshow/6.jpg',
'images/bgshow/7.jpg',
'images/bgshow/8.jpg',
'images/bgshow/9.jpg',
'images/bgshow/10.jpg',
'images/bgshow/11.jpg',
'images/bgshow/12.jpg',
'images/bgshow/13.jpg',
'images/bgshow/14.jpg',
'images/bgshow/15.jpg',
'images/bgshow/16.jpg',
'images/bgshow/17.jpg'
);
var preloadArr = new Array();
var i;
/* preload images */
for(i=0; i < imgArr.length; i++) {
preloadArr[i] = new Image();
preloadArr[i].src = imgArr[i];
}
var currImg = 1;
var intID = setInterval(changeImg, 150);
/* image rotator */
function changeImg() {
$('#page-wrap').animate({opacity: 0}, 0, function() {
$(this).css('background','url(' + preloadArr[currImg++%preloadArr.length].src +') top center no-repeat');
}).animate({opacity: 1}, 0);
}
Would appreciate your help a lot!
That script will keep changing images every 150ms, due to the setInterval(changeImg, 150) call. Thus, to stop it, you need to clear the interval when you are done changing all your images. This can be done at the end of your changeImg function, add the following;
function changeImg() {
// animation code...
if (currImg == preloadArr.length) {
clearInterval(intID);
}
}
if (currImg == preloadArr.length) run not clearInterval(intID); always currImg == 0;
In fact; currImg++ add Before or "if (currImg++ == preloadArr.length)"
function changeImg() {
// animation code...
if (currImg++ == preloadArr.length) {
clearInterval(intID);
}
}

Categories

Resources