SetTimeout will not work on Internet Explorer - javascript

On my website I have CD offers that rotate through every five seconds. This works on all browsers apart from internet explorer where it remains on the first CD.
function updateTarget( txt ) {
'use strict';
document.getElementById('offers').innerHTML = txt;
}
window.onload = function() { // attach an onload handler
getOffers(); // call the function below, getQuotes()
};
var getOffers = function() {
// call getRequest with the url, the callback, displayQuotes, and false meaning not xml
getRequest('getOffers.php', updateTarget, false);
setTimeout(getOffers, 5000); // set a timer to call this same function again in 5 seconds
};
I have tried setting the date in the header to a date in the past but this did not work. I have tried to use setinterval but again no luck.
Any help on this would be appreciated.

Related

Wait before a javascript function can be called again

I've looked at many different solutions to this, none of which worked. I know it has something to do with setTimeout, but I don't know how to implement it properly.
function myfunction()
{
//the function
//wait for 1 second before it can be ran again
}
To clarify: I don't want to call the function at a regular interval, I want to be able to enforce a delay before the function can be called again.
var lastTime = 0;
function myFunction() {
var now = new Date().getTime(); // Time in milliseconds
if (now - lasttime < 1000) {
return;
} else {
lastTime = now;
}
// rest of function
}
You don't need to use setTimeout at all. The following is similar to other answers, but uses a closure to remember the last time the function ran rather than a global variable.
var myFunction = function() {
var lastTime = new Date();
return function() {
var now = new Date();
if ((now - lastTime) < 1000) return;
lastTime = now;
/* do stuff */
};
}());
I think the easiest solution would be to hold a boolean variable and reset it to true after a given delay.
fiddle
HTML
<button id="clickme">click me!</button>
JavaScript
var canGo = true,
delay = 1000; // one second
var myFunction = function () {
if (canGo) {
canGo = false;
// do whatever you want
alert("Hi!");
setTimeout(function () {
canGo = true;
}, delay)
} else {
alert("Can't go!");
}
}
$("#clickme").click(function(){
myFunction();
})
With this, you hold a boolean, canGo, and set it to true. If the function is run, it sets canGo to false and sets a setTimeout() for a time period of delay, in milliseconds. If you try to run the function again, it won't run and will, instead, alert("Can't go!"). This was just for demonstrative purposes; you don't need that part. After delay, canGo will be set to true, and you will be able to once more run the function.
var lastRan = 0;
var myFunction = function() {
var now = Date.now();
if(now-lastRan < 1000) {
return;
}
lastRan = now;
//rest of function
};
You may want to use throttle or debounce from underscore.js
http://underscorejs.org/#throttle
throttle_.throttle(function, wait, [options])
Creates and returns a
new, throttled version of the passed function, that, when invoked
repeatedly, will only actually call the original function at most once
per every wait milliseconds. Useful for rate-limiting events that
occur faster than you can keep up with.
By default, throttle will execute the function as soon as you call it
for the first time, and, if you call it again any number of times
during the wait period, as soon as that period is over. If you'd like
to disable the leading-edge call, pass {leading: false}, and if you'd
like to disable the execution on the trailing-edge, pass {trailing:
false}.
var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);
http://underscorejs.org/#debounce
debounce_.debounce(function, wait, [immediate])
Creates and returns a
new debounced version of the passed function which will postpone its
execution until after wait milliseconds have elapsed since the last
time it was invoked. Useful for implementing behavior that should only
happen after the input has stopped arriving. For example: rendering a
preview of a Markdown comment, recalculating a layout after the window
has stopped being resized, and so on.
Pass true for the immediate parameter to cause debounce to trigger the
function on the leading instead of the trailing edge of the wait
interval. Useful in circumstances like preventing accidental
double-clicks on a "submit" button from firing a second time.
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
If you just want to run your function again after a set time, you can use setTimeout and pass it the function to run and the delay period in milliseconds.
function myfunction() {
//the function
//run again in one second
setTimeout(myfunction, 1000);
}
Edited based on poster's comments:
var waiting = false;
var myfunction = function() {
if (!waiting) {
//Run some code
waiting = setTimeout(function() {
waiting = false;
}, 1000);
}
};

Anomaly in setInterval function in asynchronous functions calls in Javascript

Below is the snippet of the code I am preparing to build a website.
<script type="text/javaScript">
function h(d) {
console.log("hello");
return;
};
function func(callback) {
var httpRequest; // create our XMLHttpRequest object
if (window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// Internet Explorer old versions
httpRequest = new
ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.onreadystatechange = function() {
// inline function to check the status
if (httpRequest.readyState === 4 &&
httpRequest.status === 200) {
callback(httpRequest.responseText);
// call the callback function
}
};
httpRequest.open("GET", '/try_ajax',true);
httpRequest.send();
}
// call the function
setInterval(func(h), 10000); // Timer is triggered here
</script>
Interestingly, though I have set the interval at 10 seconds, in my console the "hello" is appearing only once. But it should keep appearing after 10 seconds. Please help!
this is wrong
setInterval(func(h), 10000); // Timer is triggered here
You are saying take whatever is returned from func(h) and assign it to the timeout
setInterval(function(){func(h);}, 10000); // Timer is triggered here
You are actually calling the function in your setInterval call, which is not what you want. You should only give a reference to it and put parameters as the last arguments, like this:
setInterval(func, 10000, h); // Timer is triggered here
I'd like to give a shoutout to some who pointed out that the OP wanted additional parameters with his callback, something that I completely missed in my initial answer.
Fact of the matter is - when you do
setInterval(func(h), 10000)
return value of func(h) is called every 10 seconds. Your func(h) returns void. Therefore in effect after the first call, there is nothing to call for the setInterval function. Therefore you see the first invokation and nothing after that!

Trying a infinite loop on JavaScript

I am trying to do a infinite loop, but it only works if I include an 'alert' on it. My code looks like this:
while( tocontinue ){
// Some code
alert('Accept to continue');
}
On this way, the user has to click to hide the alerts (for example, on Chrome), and then the loop continues correctly by itself. I need to implement this without any alert. I also tried this:
while( tocontinue ){
// Some code
tocontinue = false;
setTimeout(function(){tocontinue=true},500);
}
And with "window.setTimeout" too, and without the word "function(){}", but it doesn't work. I tried everything: some implementations on JavaScript of a sleep() function, calling the function each X time with setInterval, answers 1 and 3 on this post... :/
Thank you very much for your time.
I'm trying to implement a genetic algorithm, and I want to stop it when I decide (with a button that puts the global variable "tocontinue" to false). Meanwhile, I want a infinite loop.
Well, you won't be able to combine a true infinite loop with user interaction as they'll both be dependent on the same thread being able to work on them exclusively. But, you can get close with a near-instant interval.
var interval = setInterval(function () {
// some code
}, 10);
Possibly grouping a few iterations together for each round:
var interval = setInterval(function () {
var limit = 5;
while (limit--) {
// some code
}
}, 10);
But, the interval will keep the iteration going as quickly as possible while still giving some idle time for user interactions, like clicking a particular button to clear the interval.
document.getElementById('stopButton').addEventListener('click', function () {
clearInterval(interval);
}, false);
Example: http://jsfiddle.net/coiscir/xZBTF/
setInterval() may be more useful here.
function updateLoop() {
//All the code goes here
}
setInterval(updateLoop,500);
var reader = new XMLHttpRequest() || new ActiveXObject('MSXML2.XMLHTTP');
function loadFile() {
reader.open('get', 'ccc.txt', true);
reader.onreadystatechange = displayContents;
reader.send(null);
}
function displayContents() {
if(reader.readyState==4) {
var el = document.getElementById('main');
el.innerHTML = reader.responseText;
var data = el.innerHTML;
}
}
for(var I = 7; I >1; i+=3);
console.log(i)

What is the optimal way to use setInterval in jquery ajax calls?

I am using JQWidgets to create a pie chart. And while that is all fine and dandy and working like a charm. What I'd like to do however is update the data every x number of seconds. Using jQuery, here is the code that I have so far:
function loadChart(id,name){
//chart loads here
var speed = 5000,
t = setInterval(reloadData,speed);
function reloadData() {
source.url = 'data.php?id='+id;
var dataAdapter = new $.jqx.dataAdapter(source);
$('#pie').jqxChart({ source: dataAdapter });
console.log('reloading pie...'+globalPieId);
speed = 5000;
clearInterval(t);
t = setInterval(reloadData, speed);
}
}
My issue is, that if the loadChart function is called, another instance of setInterval is created, and after three or four times, the chart is in a constant state of refresh. How do optimize my setInterval call so that only one instance is called?
Thanks in advance.
Instead of using setInterval which calls the function over and over again you would be better off using the setTimeout function which will call the callback you specify just once. Once that callback is called you can once again call setTimeout and you'll stop having the problems you're having right now. Also you'll wait until the last call is done before you start doing another one which is also good. The code might look something like this with the change:
function loadChart(id,name){
//chart loads here
var speed = 5000,
t = setTimeout(reloadData,speed);
function reloadData() {
source.url = 'data.php?id='+id;
var dataAdapter = new $.jqx.dataAdapter(source);
$('#pie').jqxChart({ source: dataAdapter });
console.log('reloading pie...'+globalPieId);
speed = 5000;
t = setTimeout(reloadData, speed);
}
}
For a working poc you could see http://jsfiddle.net/9QFS2/
You need to clear existing interval before you set up a new one. Try the following trick.
function loadChart(id, name) {
// We use a trick to make our 'interval' var kinda static inside the function.
// Its value will not change between calls to loadChart().
var interval = null;
// This is the core of a trick: replace outer function with inner helper
// that remembers 'interval' in its scope.
loadChart = realLoadChart;
return realLoadChart(id, name);
function realLoadChart(id, name) {
var speed = 5000;
// Remove old interval if it exists, then set up a new one
interval && clearInterval(interval);
interval = setInterval(reloadData, speed);
function reloadData() {
// ... your code, but no do nothing with interval here ...
}
}
}

Keypress with delay, how to limit to only one execution of function call?

I'm setting up a form to lookup or create a new city record in a web app. I need the text field for the city to do the following:
Upon receiving text input, show a "spinner" indicating the computer is processing the input.
After the user has stopped typing for 1 second, send an ajax request to check the input.
Respond with the status (whether the input is valid).
I have this almost working but I have one major issue: the delay script I wrote works but after the delay is over it runs the rest of the function once per keyup that occurred during the delay. I would like it to only run once. Here's the code I'm working with (the console log events would be replaced with other function calls later):
$(function() {
locationSelector.initialize();
});
var locationSelector = {
initialize: function() {
locationSelector.bindCityName $('input#city_name')
},
city: {
status: function( status ) {
console.log( "Status message: " + status );
},
error: function(message) {
console.log("Error message: " + message );
}
},
bindCityName: function(selector) {
selector.on('keyup', function() {
locationSelector.city.status('loading');
var timer = null;
if(timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(
function() { locationSelector.getCity( selector ); },
1000
);
});
},
getCity: function(selector) {
if( selector.val() == "" ) {
locationSelector.city.error('Cannot be blank.');
} else {
console.log("AJAX REQUEST");
}
}
};
Why is the getCity function is being run once per keyup, and how can I fix that? Also, to be honest I'm very much a javascript novice, so I would appreciate any other suggestions on how to improve this code scaffold.
Thanks!
For starters, the variable declaration for timer needs to be in a scope that lasts from one key event to the next. As it is, it is a local variable that gets recreated from scratch on every key event so you're getting multiple timers going at once.
Move this:
var timer = null;
to the global scope or a higher scope that persists from one key event to the next. You can also define the timer variable as a property of location selector if you want:
var locationSelector = {
// other properties defined here
timer: null
}
Then, you can refer to it as locationSelector.timer. I'd also suggest that when your timer actually fires that you should set locationSelector.timer = null since a timer is no longer active.
It also looks like you'll need to clear the 'loading' status once you run the ajax.
And, your timer is set for 2 seconds, but you said you want to wait 1 second for no typing.
It looks like the problem is here:
var timer = null;
if(timer) {
window.clearTimeout(timer);
}
Timer gets set to null, so it never gets cleared. I'd suggest declaring timer at the top, above initialize, and then setting it to null only after you clear it, or after it gets executed.

Categories

Resources