I'm working on this automated, non-endless slideshow, with dynamically loaded content. Each image has to be acompanied by sound. So far I got dynamic loading of both images and sounds down. But it all happens at once, which it shouldn't. I figured, that setTimeout can come in handy here, to set the interval between each pair, but all I got is either last image multiplied by the iteration count or script not working at all. delay also didn't prove to be of any help.
Here's whot I got so far:
function displayImages(data){
var count = data;
var pixBox = $('#picture-box');
var imgPre = 'resources/exhibit-';
var imgExt = '.png';
var sndExt = '.wav';
for(i = 1; i < count; i++) {
var imgSrc = '<img src="' + imgPre + i + imgExt + '">';
var sndSrc = new Audio(imgPre + i + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
}
}
My question is: how to set the setTimeout (or whatever function is the best here), for it to iterate over time. Say, to set the change of img/sound pairs every 2 seconds?
You can use setTimeout like this:
function displayImages(cur, total){
var pixBox = $('#picture-box');
var imgPre = 'resources/exhibit-';
var imgExt = '.png';
var sndExt = '.wav';
var imgSrc = '<img src="' + imgPre + cur + imgExt + '">';
var sndSrc = new Audio(imgPre + cur + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
return setTimeout( 'displayImages(' + ((cur+1)%total) + ',' + total + ')', 2000 );
}
And start it off like this: displayImages(0,total) where total corresponds to your data variable.
The reason I like to use setTimeout and not setInterval in these situations is that setTimeout is only called after the previous function has completed. setInterval can get back-logged and freeze up your page.
Note that the function returns a handle for the timeout. If you should want to stop the animation, you can do this:
var animation = displayImages(0,total);
...some code...
clearTimeout(animation);
and the animation will stop.
You can use a setInterval, this does the same code at every interval.
var myInterval = window.setInterval(displayImages, 2000);
This will make sure your function gets called every 2000 milliseconds.
More information on MDN setInterval
You can try something like this
$(function() {
var count = 100;
var i = 0;
var repeat = setInterval(function() {
if (i <= count) {
var imgSrc = '<img src="' + imgPre + i + imgExt + '">';
var sndSrc = new Audio(imgPre + i + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
i++;
}
else{
i = 0; //reset count if reaches threshold.
}
}, 5000); //5 secs
});
With this, if you want to reset the interval on any event you can simple call
clearInterval(repeat);
See a setInterval example here: JSFiddle
var i = 0;
setInterval(fadeDivs, 3000);
function fadeDivs() {
i = i < images.length ? i : 0;
$('#my-img').fadeOut(200, function(){
$(this).attr('src', images[i]).fadeIn(200);
})
i++;
}
Related
I'm currently writing a script in google apps script to get a list of stores in a specific location that meet my text search. I'm trying to set a timeout function for when I'm trying to receive the next page of results from google places api, and for some reason it keeps telling me that error: setTimeout function is missing a formal parameter. I've looked at everything online and the way I have it in my code looks like all the other ways to execute that function. If anyone could help me out that would be great! Thanks!
Here is my setTimeout function
function setTimeout( function(){
while(tempPage != null){
count = count++;
var nxtUrl = "https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken=" + tempPage + "&location=41.661129,-91.530167&radius=8050&key=" + apiKey;
var tempResponse = UrlFetchApp.fetch(nxtUrl);
var tempJson = tempResponse.getContentText();
Logger.log(tempResponse);
tempPage = JSON.parse(tempJson).next_page_token;
Logger.log("Page count: " + count);
for(var j = 0; j < 20; j++){
var tempPlace = JSON.parse(tempJson).results[j];
Logger.log("Name: " + tempPlace.name);
Logger.log("Address: " + tempPlace.formatted_address);
}// end for loop
}// end while loop
}, 3000);
Google apps script does not use the setTimeout function. The solution is to use Utilities.sleep() function instead.
Utilities.sleep(3000);
while(tempPage != null){
count = count++;
var nxtUrl = "https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken=" + tempPage + "&location=41.661129,-91.530167&radius=8050&key=" + apiKey;
var tempResponse = UrlFetchApp.fetch(nxtUrl);
var tempJson = tempResponse.getContentText();
Logger.log(tempResponse);
tempPage = JSON.parse(tempJson).next_page_token;
Logger.log("Page count: " + count);
for(var j = 0; j < 20; j++){
var tempPlace = JSON.parse(tempJson).results[j];
Logger.log("Name: " + tempPlace.name);
Logger.log("Address: " + tempPlace.formatted_address);
}// end for loop
}// end while loop
I have a setTimout loop being called repeatedly but the loop seems to catch up with itself and causes sticking on my page ect. I added a alert to see what was happening and i had the timer set to call every 10seconds, but the alert was being displayed oppressively faster until it was continuous
can anybody see why this is by my code below.
Many thanks
$(function(){
var running = setTimeout(function (){
var varLISTID = document.getElementById('datacatch').getAttribute("data-variable-LISTID");
var varUSERACCOUNTNAME = document.getElementById('datacatch').getAttribute("data-variable-USERACCOUNTNAME");
var varITEMACCOUNTNAME = document.getElementById('datacatch').getAttribute("data-variable-ITEMACCOUNTNAME");
var varSELECTEDUSER= document.getElementById('datacatchuser').getAttribute("data-variable-SELECTEDUSER");
var mylink = "loadmessages.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER;
$('#infobox1').load(mylink);
var myotherlink = "contactselect.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER;
$('#containercontact').load(myotherlink);
},10000);//10s
$(document).keypress(function() {
clearInterval(running);
})
});
function SlideShow(area)
{
var SlideImg = new Array('img1', 'img2');
var SlideArea = document.getElementById(area);
for(i=0;i<SlideImg.length;i++)
{
var html = '<img src="images/room/' + SlideImg[i] + '.jpg" id="' + SlideImg[i] + '" class="not-active" />';
SlideArea.innerHTML += html;
}
var a = 0;
function RunSlide()
{
document.getElementById(SlideImg[a]).className = 'active';
a++;
}
var run = setTimeout('RunSlide()', 5000);
}
This function not working after I add the setTimeout() method there. Can anybody help me?
Just change it to:
var run = setTimeout(RunSlide, 5000);
The reason is: when you pass a string to setTimeout() it is evaluated in global context - where RunSlide is not visible, because it is local.
Passing a string to setTimeout() is never a good idea, here you have one reason.
So I have the following code which i basically just a JSON string I am using eval to convert to an object. Now, this object has an array of elements that gets displayed to the screen via a for loop:
function DisplayListing(str)
{
var obj = eval("(" + str + ")");
var div = document.getElementById('Response');
for(i=0; i<obj.files.length; i++)
{
div.innerHTML += '<span id="listing' + i + '" class="displayNone"><img src="' + obj.files[i].icon + '"/>' + obj.files[i].name + '</span><br />';
}
}
This works just fine. However, what I want it to do is wait a set interval of time before it continues to the next element. I want to it basically call a function with a timeout, so each element fades onto the screen individually. All attempts so far on cause the last element to execute a function. Any help would be greatly appreciated!
http://jsfiddle.net/SfKNc/
var obj = {files: [1, 2, 3]}; // sample object - use JSON.parse by the way
var div = document.getElementById('Response');
for(var i=0; i<obj.files.length; i++) { // use var!
setTimeout((function(i) {
return function() { // i changes, so create a new function in which i does not change
div.innerHTML +=
'<span id="listing' + i +
'" class="displayNone">' + i +
'</span><br />';
};
})(i), i * 1000); // set timeout to 1000 ms for first item, 2000 for second etc.
}
you have manually create a sleep function something like the below:
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
or you create an empty function and use the setTimeout on it
function sleep()
{
setTimeout(Func1, 3000);
}
Func1(){}
http://www.phpied.com/sleep-in-javascript/
This has probably been answered before and I already know how this should work, but for some reason it is not. I think it may be how I am looping through the elements.
$(document).ready(function() {
var element = '#gallery ul#gallery-container';
var idx=0;
var timeout = 3000;
var number = $(element + ' li').length;
function changeSlide() {
$(element + ' li:eq(' + idx + ')').fadeOut();
idx = idx + 1;
if (idx == number) {
idx=0;
}
$(element + ' li:eq(' + idx + ')').fadeIn().delay(timeout).delay(0, function() {
changeSlide();
});;
}
$(element + ' li').hide();
$(element + ' li:first').fadeIn().delay(timeout).delay(0, function() {
changeSlide();
});
});
Then the list is like this:
<div id="gallery">
<ul id="gallery-container">
<li><img src="media/images/screen-shot-02.jpg" width="173" height="258" alt=" "></li>
<li><img src="media/images/screen-shot-01.jpg" width="173" height="258" alt=" "></li>
</ul>
</div>
I was trying to get it to loop through the elements one by one, after a delay so the list item calls the function and hides itself, then the counter is incremented and then the current index is shown.
I suspect the culprit to be this as if I put an alert in the function it is called:
$(element + ' li:eq(' + idx + ')').fadeOut();
The main problem is, as the comment states, delay does not do what you think it does - you should be looking at the native setTimeout function instead. In addition to that, there are multiple places where this could be made more efficient. Have a look at this:
var element = $('#gallery-container li'),
length = element.length,
current = 0,
timeout = 3000;
function changeSlide() {
element.eq(current++).fadeOut(300, function(){
if(current === length){
current = 0;
}
element.eq(current).fadeIn(300);
});
setTimeout(changeSlide, timeout);
}
element.slice(1).hide();
setTimeout(changeSlide, timeout);
We try not to evoke the jQuery function with a dynamically generated selector, but instead manipulate a single instance of a jQuery object containing all the slides cached at the start. We also use the callback function provided by the fade functions to fade in the next slide after the current one has faded out.
See http://www.jsfiddle.net/b3Lf5/1/ for a simple demo
I would do it something like this:
$(document).ready(function() {
var element = '#gallery ul#gallery-container';
var idx = 0;
var timeout = 3000;
var number = $(element + ' li').length;
setInterval(function () {
idx = (idx + 1) % number;
$(element + ' li:visible').fadeOut();
$(element + ' li:eq(' + idx + ')').fadeIn();
},timeout);
$(element + ' li:not(:first)').hide();
});
Or better still, wrap it in a plugin:
(function ($) {
$.fn.customGallery = function (options) {
defaults = {
timeout : 3000
};
options = $.extend(defaults, options);
return this.each(function () {
var idx = 0, number = $(this).children('li').size(), element = this;
setInterval(function () {
idx = (idx + 1) % number;
$(element).children('li:visible').fadeOut();
$(element).children('li:eq(' + idx + ')').fadeIn();
},options.timeout);
$(element).children('li:not(:first)').hide();
});
};
}(jQuery));
jQuery(document).ready(function($) {
$('#gallery-container').customGallery()
});
edit: Edited the plugin code to bring it into line with good practice.