I have a page that needs to be refreshed every 60 seconds. On this page I am using iBox to popup various items. My problem is that a meta refresh kills the popup which is not wanted. Please keep in mind I have zero to little experience with javascript so my solution may be fundamentally wrong.
The solution I came up with is to use javascript to do the refresh. When the page loads I will start the timer, when an ibox pops up I will clear the timer, when the ibox closes I will start the timer again.
I am setting this up by using a simple function.
function timedRefresh(timeoutPeriod){
var resetId = 0;
resetId=setTimeout("location.reload(true);",timeoutPeriod);
}
Then I call the function <body onload="timedRefresh(60000)">.
My problem is stemming from when I try to call clearTimeout(resetID). I am trying to call the method from the ibox script's hide function, but it doesnt actually clear out the timer. I think it may be a scope issue and I may need to do some sort of Object.clearTimeout(Object.resetID) but that is just a guess.
Do this:
function timedRefresh(timeoutPeriod){
window.resetId = 0; // make it clear it's global by prefixing "window."
window.resetId=setTimeout("location.reload(true);",timeoutPeriod);
}
Then from the relevant ibox function use window.resetId.
Seeing your comment I'll add something.
"window." will work when scripting within a browser, should you use JS somewhere else it probably won't work.
As long as you're on a webpage, however, window is the global object and the "window." prefix is IMO a good way to make it clear that certain variables are global; if you use it consistently, all the variables that don't have "window." in front of them are always local.
You should know, however, that it would also work if you simply used resetId without any prefix and without var because any variable that isn't declared with var is automatically scoped to window.
This short-ish guide will teach you most of what you need to know about variable visibility in Javascript, execution contexts and closures. It will send you on your way to become a deadly Javascript ninja.
You're right, the problem is the scope of the variable resetId. As you declare it in the function with the var keyword, it is local to this function, and thus does not exist outside of it.
Simply declare resetId outside of the function to make it global, and you'll be fine :
var resetId = 0;
function timedRefresh(timeoutPeriod){
resetId=setTimeout("location.reload(true);",timeoutPeriod);
}
I'd suggest making the content on the page, that needs to be refreshed, updated through ajax. Here is a link to a tutorial http://www.w3schools.com/Ajax/Default.Asp
The easiest way is to add the resetId variable to the global scope:
var resetId = 0;
function timedRefresh(timeoutPeriod){
resetId=setTimeout("location.reload(true);",timeoutPeriod);
}
Alternatively, you might be able to define the iBox's hide function in the same scope, but I'm not too sure how iBox works.
More reading on scopes: http://javascript.about.com/library/bltut07.htm
Related
var variableOne;
var variableTwo;
var variableThree;
function veryInterestingFunction() {
var variableFour;
if(a){
variableFour = 'Good';
}
else {
variableFour = 'Decent';
}
console.log(variableFour);
}
$(window).on('scroll', function(){
veryInterestingFunction();
});
Here I have some variables in the global scope, a function declaring a variable and assigning a value to it, and calling this function on scroll.
This way on every scroll you are going to declare the "variableFour" which is not a good practice, right?
However I don't want to crowd the global scope with unnecessary variables and also can't use an IIFE. Is there a "best practice" way to declare the variable outside the function and still only possible to use it inside the scope of that function ?
http://jsfiddle.net/2jyddwwx/1/
to declare the variable outside the function and still only possible to use it inside the scope of that function ?
I guess, that's impossible
When I don't want to crowd the global scope, I will declare one global object, for example App = {}, and instead of global variables, I use it's properties.
App.variableOne;
App.variableTwo;
App.variableThree;
Or you can use classes in ES6
I don't think there's anything wrong with your code sample, I seriously doubt variable declaration is ever going to slow down your code. I'd definitely only start to worry about this kind of thing when you're absolutely certain it's causing issues (it won't), otherwise it might be wasted effort.
If you really want to optimize this, one thing you might be able to do is debouncing the veryInterestingFunction calls - that is if you don't necessarily need to respond to every single scroll event (depends on your logic).
As per your question, IIFE/function closure is essentially the only way to limit scope in JavaScript that I know of, so if you can't use that, I don't see any other option.
There is no problem in declaring an empty variable into your scope. If it is not global, it belongs to the scope.
And there is no need to fear for performance. If you declare variables within your scope, the Javascript garbage collector will empty that for you. Take a read at this article
If I have the following JavaScript code:
<script id="someJS">
var boom = 'boom';
function example(){
alert(boom);
}
</script>
and then do:
$('#someJS').remove();
I can still call example() even though that JavaScript function is no longer inside the DOM... How can I remove it?
I don't want to null the actual function(s) and variables with: boom = null; example = null; as I don't always know what is inside the JavaScript file. For example the function names, variables, etc. I need to be able to remove the entirity of what was inside that script tag.
Update: For those that wanted to know the user case for this:
Basically in an app I am working on, we have custom JavaScript added for certain clients that when a button is clicked e.g. save, then checks if certain functions exist and then runs them. However because this save button is generic it means that that the custom code gets called all the time after it's added even if it's no longer relevant.
The solution we have come up with (someone had posted this as an answer but they removed it for some reason) was to namespace it all like:
DynamicJS = {
boom: 'boom',
example: function(message) {
alert(message);
}
}
And then we can just do: delete DyanmicJS;
Which removes all the functions and variables inside this namespace from the global scope, effectively binning off what the script file added.
Although I am sure this is not a perfect solution as if you had event listeners inside the file, I'm sure they would still exist!
How can I remove it? I don't want to null the actual function, as I don't always know what is inside the JS file.
You can't. Script code is executed, creates things in the JavaScript environment, and is completely disconnected from the script element that loaded it. Other than completely reloading that environment, if you don't know what the code did, you can't undo it.
Even if you could infer some of what the code did (for instance, by making a list of globals before and after), while you could remove new globals you detected (or at least set them to null or undefined, since delete doesn't work wiith globals added via function declarations or var), that doesn't tell you what event handlers, web workers, etc. the code may have hooked up.
$('#someJS').remove(); only removes the script element from the page.
By the time the element is removed, the script has already been interpreted, which means example has been added to the global scope.
To properly remove that function you could do this:
window.example = null;
However, apparently you don't want to do this, and this will result in a load of errors if there's script elsewhere that actually uses example.
An alternative could be to assign an empty function to it:
window.example = function(){};
This will prevent the "removal" from resulting in errors.
(Aside from the function not returning values when that may be expected)
Once the function has been processed, it is now part of the window's executable list of functions - regardless of if you remove the original source or not.
To remove the function entirely, try:
window['example'] = null;
However, based on your last comment:
I don't want to null the actual function, as I don't always know what is inside the JS file.
It sounds like you want to maintain reference to the function but not have it executable directly? If that's the case, you can store a reference to it and remove the original:
var _exampleBackup = window['example'];
window['example'] = null;
To call it, you can now use:
_exampleBackup();
And to restore it, if you need to:
window['example'] = _exampleBackup;
example();
That function is still in the window.
Code that you put inside a script tag will be ran when the element is created and has no value (roughly) by itself anymore. Removing the tag will not affect the document and the impact it had on it (generally).
To remove the function you need to remove the example property on the window object, which is how the function will be defined, running the code above.
$('#someJS').remove();does nothing more than removing the text from the DOM, but does nothing to the actual function (nor the file), since it is parsed and executed.
In order to delete the function, you could either set it to null or simply overwrite it with example=function(){};
JavaScript Hoisting
There is a concept in JavaScript called Hoisting. In this phase, compiler parse all JavaScript code and declares variables and function at the beginning of scope. In your case, function example and variable boom is already declared and kept in memory. When you run that method, interpreter will call that method and interpret it instead of interpreting actual JavaScript code. You are deleting script block after it went in memory. And thats why it is still executable.
Approaches to do this
1) Use object oriented approach. Add your method in a object, and when you want to delete it, delete that property by using delete.
2) Create one variable which holds a function which contains your code to execute, and set that variable undefined when you want.
I'm struggling with (what I believe to be) a scoping issue. Here's a sample of my code:
$(document).ready(function() {
var counter = 0;
function scrollTweets() {
counter ++;
// rest of code
}
...
)}; // end of document ready
When I look up the variable counter in Chrome's Javascript console it returns "ReferencedError". However, when I remove var from the code above and type counter into the console, it returns the value. Why is this?
I think understanding this simple concept would allow me to tackle issues that seem to pop up during development. Is it just a scoping issue on Chrome's part? Am I needlessly wrapping everything in the $(document).ready "function"?
The var locks the variable counter into whatever the lexical scope is -- which means its available in the current block, method, whatever, and can be attached to closed-in scopes (ie. closures), like you are doing with scrollTweets. So counter is only available in the ready callback and anything that has a closure around it, which is why you can't access it from your console.
When you take the var away, counter is effectively global, which is why you can access it in that case.
When you don't use var to set the scope of the variable, it automatically becomes a global variable, inside the global scope. That's why it is visible in the Chrome console.
As a note, I'm by no means implying you should make the variable global. In fact that's almost always a bad idea! Capturing the variable in the context of the scope where it's used is the right thing to do. If the Chrome console can't handle that you just need a better debugger. Firebug for Javascript does a wonderful job at handling scope - even clojures!
I have something similar to this
function testfunction(runthis)
{
runthis();
}
function main()
{
var z = 15;
testfunction(function(){ alert(z); });
}
However it doesn't think z is in the same scope as my inline function. Without adding additional parameters to testfunction or my inline function, is there any way for my inline function to belong to the same scope as main? I'm trying to make callback functions work.
Edit: the above I imagine is a crappy example because it seems to be working. However the instance here http://pastebin.com/A1pq8dJR does not work unless I add .call(this,parameters) and manually set the scope (although I'm not exactly sure what this is doing). I would have thought this used there would refer to the scope imageLoaded has, but it is referring to the scope of imageBoxCreate? Could anyone explain why it wont work without that and why doing this fixed it?
If you just invoke a global function in javascript, the this object will be the top level window global object. If you invoke a function using the dot operator on an object, then this will be that object when the function runs. When you use function.call, you are explicitly specifying which object should be this. I think you are likely just making some scope mistakes with how you use this and var, but your code is long enough and involved enough that I'm not going to spend the time to debug it for you. If you can isolate you issue with a smaller code sample, folks should be able to help more easily.
Many thanks in advance. I'm working out of a schoolbook and they're using one function to call another which opens a window:
function rtest(){
content='dans window';
oneWindow=open("","Window 1","width=450,height=290");
newWindow(oneWindow);
}
function newWindow(x){
x.document.close();
x.document.open();
x.document.write(content);
x.document.close();
x.moveTo(20,20);
x.focus();
}
So everything works fine, but my question is this: how is the newWindow() function able to access the contents of the "contents" variable in the rtest() function? And why, if I preface the "content" variable with "var", like this:
function rtest(){
**var content='dans window';**
oneWindow=open("","OneWindow","width=450,height=290");
newWindow(oneWindow);
}
...does an error get thrown (and the contents of the new window left blank)?
Can anybody explain to me what the difference between using var and not using var is?
Thank you!
Daniel
if you dont use var inside the rtest, it is automatically a global variable. which is why it is accessible from other javascript codes including newWindow. now, when you use var, it automatically a variable inside the rtest scope, so the ones that can use it now are those inside the same scope.
If you declare the variable using var inside the original function, it will become a local variable and will not be visible outside the function.
If you don't declare the variable at all, it will be global. However, best practice is to declare global variables. If your textbook doesn't do this, consider replacing it. If your professor doesn't do this, consider replacing (or reforming) him. :-) If you have trouble convincing him, you can (but not necessarily should) mention that I'm one of the top 200 users here.
For example:
var content;
function rtest(){
content='dans window';
oneWindow=open("","Window 1","width=450,height=290");
newWindow(oneWindow);
}
Also, the best way to open a blank window is to call open("about:blank", ...), not open("", ...).
It's about the function-scope, if you declare your variable with var, it will be available only in the scope of the function where you did it.
If you don't use the var statement, and you make an assignment to an undeclared identifier (an undeclared assignment), the variable will be added as a property of the Global object.
If you don't use var, then you are creating a global variable; that is, a variable that is accessible from any code anywhere in your program. If you use var, you are creating a local variable, which is a variable that is only accessible from within the scope in which it is defined (generally, the function it is defined in).
While global variables can be convenient at first, it's generally a bad idea to use them. The problem is that all of your code will share that one global variable; in the future, if you need to have two or more different versions of that variable for whatever reason, you won't be able to separate the two uses. Global variables can also be accessed or changed from anywhere within your program, so it can be hard to figure out what might be modifying or depending on one, while local variables can only be accessed within a limited, well defined section in code, which can easily be inspected.
With var you declare a local variable in the function which is thus not visible outside this function. Without var you are actually working on the window object and set or overwrite a field of it. Your global scope in client side Javascript is always the window object. So you could also have written window.content='dans window'; to make clearer what you are actually doing there, but otherwise it would be identical. By the way: the window variable is itself just a field of the window object that refers recursively back to the window.