I am using an already defined function and now want to add a pollServer function to it so that this functions runs over and over. I keep getting errors when I try to wrap the existing function in another. Is there a better way to do this?
function callD(id) {
jQuery('document').ready(function pollServer(){
window.setTimeout(function () {
var ab = document.getElementById('a')
console.log(ab);
var bod = document.getElementById(+id)
if (ab == null) {
bod.style.background='green'
} else {
bod.style.background='blue'
}
}, 1200);
})
}
callD();
pollServer();
pollServer isn't defined where you're calling it. Also id isn't being passed to callD, and you also have a +id which doesn't make sense in a document.getElementByid, since if there's any non-number in the ID, that would be NaN. You're also not polling a server, you're setting a timeout once and doing some work that doesn't involve a server. You would want setInterval for regular polling, or to call the function again on some condition like a failure.
$(document).ready(function () {
var intervalId;
function callD(id) {
function pollServer() {
intervalId = window.setInterval(function () {
var ab = document.getElementById('a')
console.log(ab);
var bod = document.getElementById(id)
if (ab == null) {
bod.style.background='green'
} else {
bod.style.background='blue'
}
}, 1200);
}
pollServer();
}
callD('some-id');
// on some condtion eventually:
clearInterval(intervalId);
})
Yeah, jQuery can make things pretty gnarly with all the nested callbacks. To make the code cleaner and easier to understand, I like to split my functions up and define them all at the top-most level of the script, then compose them together like so:
/**
* this function will check for the existing elements
* and update styles
*/
function setBodyStyle(id) {
var ab = document.getElementById('a');
console.log(ab);
var bod = document.getElementById(+id);
if (ab == null) {
bod.style.background='green';
} else {
bod.style.background='blue';
}
}
/**
* this function will create a timeout or interval
* which will in turn run setBodyStyle()
*/
function pollServer() {
// I think you want setInterval here if you're polling?
// setInterval will run _every_ 1200ms,
// setTimeout only runs once after 1200ms
window.setInterval(function() {
// not sure where you're getting id from,
// but you'll want to pass it here
setBodyStyle();
}, 1200);
}
// when the document is ready, run pollServer()
jQuery(document).ready(pollServer);
Having small functions that do one thing is just best-practice for the reasons I mentioned above. This will help your script be more understandable, which will help you find bugs.
For example, two things I don't understand about your code above:
where does the id variable come from? I don't see you passing it to your function from anywhere
how does your script poll the server? I don't see the code for that anywhere either.
Seemed you mean run the function pollServer every 1.2 sec. If so, you'd need to do two things
Use setInterval rather than setTimeout
Delete the last line for the pollServer function, because it is not accessible from outside the ready function block.
Related
I thought an interval just delayed the function, but as it turns out it actually loops.
When I include some function that stops the interval after the deletor function ends it doesn't trigger that and I still get Test logged to the console.
document.addEventListener("DOMContentLoaded", function(event) {
let fullURL = window.location.href;
//let fullURL2 = window.location.host + window.location.pathname;
if (fullURL === "https://net.adjara.com/" ||
fullURL === "https://net.adjara.com/Home") {
var timer = setInterval(deletor, 5);
function deletor() {
timer;
var slider = document.querySelector("#slider-con");
var bannerTop = document.querySelector("#MainContent > div:nth-child(2)")
var bannerMiddle = document.querySelector("#MainContent > iframe");
var bannerRandom = document.querySelector("#MainContent > div:nth-child(3)");
if (slider) {
slider.parentNode.removeChild(slider);
}
if (bannerTop) {
bannerTop.parentNode.removeChild(bannerTop);
}
if (bannerMiddle) {
bannerMiddle.parentNode.removeChild(bannerMiddle);
}
if (bannerRandom) {
bannerRandom.parentNode.removeChild(bannerRandom);
}
function stopInterval() {
clearInterval(timer);
}
console.log("Test");
/*if ()
clearInterval(timer);*/
};
} else {
return false;
}
});
What you're looking for is setTimeout. It runs only once.
setTimeout(deletor, 5);
Also, you don't need to write timer variable inside of your closure like you would in Python. Javascript captures everything that's inside of lexical scope.
The code you provided works ¯\_(ツ)_/¯
Maybe the problem is coming from what triggers stopInterval()
But as mentioned in comments / other answers, you might be better off with another method
I wouldn't recommend using setTimeout in your case, because it looks like you are simply waiting for some DOM elements to be loaded. The problem with the timeout is that you can't know for sure how fast is the computer that will run your code. Maybe a bad quality phone with an outdated software that will need way more time to run your code than when you test on your personal computer, and that will not have the elements loaded by the time your function will be executed.
jQuery
For this reason, and since you tagged your question with jQuery I think you could use $(elementYouWaitForTheDOM2beLoaded).ready(function2execute) for each element you are watching instead of a having a loop that waits for the elements to be loaded (documentation for "ready" function)
Vanilla JS
And if you want to do it in pure JS it would be document.querySelector(elementYouWaitForTheDOM2beLoaded).on('load', function2execute))
I've written some code that when you click a button it adds an instance of a function to an array,
var objects = [];
$(document).on("click", ".addButton", function(){
objects.push(new newObject(1));
});
function newObject(amount){
setInterval(function(){
addValue(amount);
}, 1000);
}
So then every second each new object created keeps running the addValue function every second adding the amount.
The problem is when I try and destroy that function with objects.pop() it deletes the object but the setInterval doesn't stop running.
How do I make it destroy everything in that function and stop it from running?
There is nothing quite like that in JS for setInterval. I would suggesting declaring a method to handle clean up.
// "Class" declaration
function newObject(amount) {
var id = setInterval(function() {
addValue(amount);
}, 1000);
this.kill = function() {
clearInterval(id);
}
}
// "Public" api for the data structure
var objects = [];
function addNewObject() {
objects.push(new newObject(1));
}
function destroyLastObject() {
objects.pop().kill();
}
// Event bindings
$(document).on("click", ".addButton", addNewObject);
$(document).on("click", ".removeButton", destroyLastObject);
Completely untested, but along these lines should work.
EDIT
This, imo, is a great resource for learning about different patterns within javascript - long but well well worth the read: https://addyosmani.com/resources/essentialjsdesignpatterns/book/
You got to find something to check against to clear the interval. I am clearing based on array length. It only executes once.
// you got to find something to check against to clear the interval
var objects = [];
document.addEventListener("click", function(){
console.log('click');
objects.push(new newObject(1));
});
function newObject(amount){
var interval= setInterval(function(){
if(objects.length !==0){
clearInterval(interval);
}
}, 1000);
}
I'm really confused how these work...the timeout does not seem to keep running it calls begin_anim once and then thats it....
So am hoping someone can see where i went wrong and explain how I implement this?
This is my code:
//test data:
//type = 'up';
//div = document.getElementById('theid');
//marginL = -400;
function timeout_begin(type,div,marginL){
setTimeout(begin_anim(type,div,marginL),1000);
}
function begin_anim(type,div,marginL){
if(type == 'up'){
if(marginL >= '-200'){
if(marginL > '-200'){
div.style.marginLeft = '-200px';
}
return false;
}
marginL += 2;
div.style.marginLeft = marginL+'px';
}
return false;
}
Hope you can help!
You're looking for setInterval!
Also, it's probably better to pass an actual function in, and you can hold a reference to the loop so you can stop it running later if you want to:
var animationLoop = setInterval(function () {
begin_anim(type, div, marginL);
}, 1000);
clearInterval(animationLoop); // This would then stop the loop.
First, you want setInterval, not setTimeout
Second, you'll pass a reference to a function, not a call to a function. Something like:
function timeout_begin(type,div,marginL)
{
setTimeout(
function() {
begin_anim(type,div,marginL);
},
1000
);
}
setTimeout is supposed to call the function only once.
if you want to call the method repeatedly use setInterval(function(){}, 1000/*duration*/)
setTimeout is only expected to execute the function once after the given timeout. See the documentation here: http://www.w3schools.com/jsref/met_win_settimeout.asp
You're probably looking for setInterval (http://www.w3schools.com/jsref/met_win_setinterval.asp) which executes the code at the interval you set until clearInterval is called.
I have a recursive type function in Javascript that runs like this:
function loadThumb(thumb) {
rotate=setTimeout(function() {
loadThumb(next);
}, delay);
}
Note: I've simplified the function to make it easier to read.
I have "a" tags called like this
Load thumb 3
However, they don't clearout the timer, the timer continues to cycle through the function irregardless of the clearTimeout() being called.
Any ideas why? I think it might have something to do with a scope problem or something like that.
Yeah, you need to make rotate a global variable. Simply declare it outside the function like so:
var rotate;
var delay = 1000;
function loadThumb(thumb) {
alert("loading thumb: " + thumb);
rotate = setTimeout(function() {
loadThumb(thumb + 1);
}, delay);
}
Also, you need to make sure you clear the timeout before you call loadThumb. Otherwise you'll clear the timer you just started.
Load thumb 3
fiddle: http://jsfiddle.net/63FUD/
it may be the issue of scope so make rotate as global variable and call clearTimeout(rotate);
refer clearTimeout() example
It may be a scoping issue if you are not declaring rotate externally.
Try this:
var rotate = 0;
function loadThumb(thumb) {
rotate=setTimeout(function() {
loadThumb(next);
}, delay);
}
Return false on the link
Since you are not using var rotate, it should not be a scoping issue since rotate would be in the window scope. Can you show the complete code?
It is considered poor coding to inline the script - you should attach the event handler onload of the page
Also you should not have the setTimeout inside a function that might be called for one image
Try this:
var rotate,next=1;
function loadThumb(thumb) {
if (thumb) ... use thumb
else ... use next
}
function slide() {
rotate=setInterval(function() {
loadThumb();
next++;
if (next>=images.length) next=0;
}, delay);
}
window.onload=function() {
var links = document.getElementsByTagName("a");
if (links[i].className==="thumbLink") {
links[i].onclick=function() {
var idx = this.id.replace("link","");
loadThumb(idx);
clearInterval(rotate);
return false;
}
}
document.getElementById("start").onclick=function() {
slide();
return false;
}
document.getElementById("stop").onclick=function() {
clearInterval(rotate);
return false;
}
slide();
}
assuming
Start
Stop
Show 1
Show 2
Show 3
If you have to manage multiple timeouts, you can use an object in the global scope and some custom methods to create and remove your timeouts. To access the methods you can either put the calls in the onclick handler of your links (like in the example), or use a library like jQuery to bind them.
<script type="text/javascript">
var timeouts = timeouts || {};
function createTimeout(name, milliseconds, callback) {
timeouts.name = setTimeout(callback, milliseconds);
}
function removeTimeout(name) {
if (typeof(timeouts.name) !== undefined) {
clearTimeout(timeouts.name);
timeouts.name = undefined;
}
}
createTimeout('foo', 5000, function() {
alert('timeout')
});
</script>
i have also posted an example on jsFiddle http://jsfiddle.net/AGpzs/
I'm not sure what exactly you are doing, because as far as I can see you didn't post all the code, but this looks better for me:
function loadThumb(thumb) {
return setTimeout(function() {
loadThumb(next);
}, delay);
}
and then:
Load thumb 3
I am having a problem where I want to stop a particular function from executing. This function is located on another plugin which I can't change the core files so I am wondering if I can stop a specific function from that file from executing?
So for example that function is testFunction(); and I want to stop that later in the code maybe in on document ready...etc.
Thanks!
Is the function public (as opposed to private via a closure)? And, does it need to be operational at all for things to work, or can you chop it out in total and be fine? If the latter, you can replace the function with a new one:
otherLibrary.testFunction = function(){};
If you want to disable it for a temporary amount of time, you can store the function in a temporary variable, and restore it later:
var removedFunc = otherLibrary.testFunction;
otherLibrary.testFunction = function(){};
// do something, time passes, whatever...
otherLibrary.testFunction = removedFunc;
Or, if you want to be able to toggle it, a slight variation:
var removedFunc = otherLibrary.testFunction;
var testFunctionEnabled = true;
otherLibrary.textFunction = function(){
if(testFunctionEnabled){
removedFunc.call(this, arguments);
}
};
And then just set testFunctionEnabled as you need to.
you should try to extend the function before you call it e.g.
$.extend(plugin.function, myNewFunction);
also, check the plugin API to see if you can pass a paramter to override the function or actually access the api of the plugin e.g.
$('#mytip').api('hover', myHoverFunction);
If you have access to the object which refers to the "testFunction" function then you could replace it with an empty function, e.g.:
SomePlugin.testFunction = function() { };
Ultimately, if you don't have a way to overwrite that symbol then there's not much you can do to stop the method from running (unless you can provide more details).
If that function schedules itself with setInterval, you can use clearInterval(thefunction) to prevent it from being called again. But if it's a loop, I don't know if that's possible.
Simply set the function to null.
JavaScript example:
function write() {
el.innerHTML += 'Lorem ipsum dolor sit amet.<br />';
if (execute != null) execute();
}
function execute() {
setTimeout(function() { write() }, 500);
}
function abort() {
execute = null;
}
window.onload = function() {
el = document.getElementById('blah');
execute();
}
HTML:
<button type="button" onclick="abort()">Abort</button>
<p id="blah"></p>
Also you can change the following to implement stop/start. For this, assign the execute function to a variable so that you can later assign that variable back to execute.
var oldfunc = execute;
function abort() {
if (execute == null) {
execute = oldfunc;
execute();
} else {
execute = null;
}
alert(execute);//shows the function code
}
You can overwite any method you have access to- but if the code in your module calls it internally you better give it an appropriate return.
document.write=function(){return true};
alert(document.write('tell me more!'))