I've had a few instances now in which I create, say, a variable with css called
.slider
and it affected alot of stuff on my page.
How do I avoid this?
Also, I've written alot of JavaScript in a plugin, and ended up doing changes to global variables.
Is there a way to avoid this? All of the sudden all the images might change on a page, or something in the javascript code changes stuff on the page.
It seems that your code looks like this:
var my_global_var = 123;
function do_something_with_vars() {
// ... your logic here
}
function do_something_else_with_vars() {
// ... your logic here
}
One way to avoid global variables conflict is to use anonymous functions:
The above code can be re-written as:
(function(){
var my_global_var = 123;
function do_something_with_vars() { ... };
function do_something_else() { ... };
})();
// here, my_global_var is out of scope.
Related
I have a functionality that I had running in the
window.addEventListener('load', function() {
var variable_name_1 = localStorage.getItem('var_1');
...
}
and I would like to move the functionality such that it only runs when the user clicks a button, in here:
function maketempuser() {
...
}
I can get the function to call when I want. But the function utilizes tons of variables from the load function. Is there a clean way to "globalize" these variables? Or must I find some way to add all these variables in the html:
<button ... onclick='maketempuser(variable_name_1, variable_name_2, ...);' >
NOTE: the javascript will run the same file, I just don't want it to keep re-running every time the user reloads the page since there is an ajax mysql insert that occurs because this page is one in a line of pages that enables a user to register.
To not pollute the global scope with a lot of variables (which can be overridden by other apps), I recommend you create an object with an app specific name, maybe something like this
var myAppVar = {};
window.addEventListener('load', function() {
myAppVar.var_1 = localStorage.getItem('var_1');
...
}
Just define them in global scope:
var variable_name_1;
window.addEventListener('load', function() {
variable_name_1 = localStorage.getItem('var_1');
...
}
This, however, is not a particularly healthy technique, since it's prone to name collisions. Best thing to do is have a custom object (cO, or with your initials, something unlikely to be used by anything else) and use it as a placeholder for all your custom vars:
var cS = {
var_1:null // or some default value...
};
window.addEventListener('load', function() {
cS.var_1 = localStorage.getItem('var_1');
...
}
Since localStorage is already global just retrieve the values you need in your handler from there.
function maketempuser() {
var variable_name_1 = localStorage.getItem('var_1');
}
No need to add anything extra to the global scope at all.
I have a js file containing my all jquery code all, I followed 2 practices but I don't know which one is better:
First:
jQuery(document).ready(function(){
var $ = jQuery;
//some code here
//another code not related to the first one
//also another independent code
//... and so on
});
Second:
jQuery(document).ready(function(){
//call the functions here
my_func_1();
my_func_2();
my_func_3();
my_func_4();
});
//list of functions
function my_func_1() {
//function code
}
function my_func_2() {
//function code
}
function my_func_3() {
//function code
}
function my_func_4() {
//function code
}
the second method seems better and more organized, but sometime let's say that my_func_2() didn't find what it's looking for on the page for example $('#my-id'), the functions that follow my_func_2() never run.
I also tried another method, define all my jquery functions in one js file, and then adding the function using script tags in the html where they should be:
<script>my_func_2();</script>
so what is the best way to group jquery code ?
and should we use :
jQuery(document).ready(function(){
});
for each bunch of code ?
and thanks in advance.
If your code in func_2() potentially causes an error then you really should be wrapping the contents of your functions in try / catch blocks to ensure that there are no issues with the next function running.
Also, the following is also an option for multiple start-up functions whilst keeping their error scopes separate:
$(document).ready(function(e) { ... My function code 1 .... });
$(document).ready(function(e) { ... My function code 2 .... });
$(document).ready(function(e) { ... My function code 3 .... });
$(document).ready(function(e) { ... My function code 4 .... });
var myFunc1 = function() {};
var myFunc2 = function() {};
var myFunc3 = function() {};
var myFunc4 = function() {};
Declare your functions first. And see this shortener for jQuery.ready
jQuery(function($) {
// in here $ === jQuery.
myFunc1();
myFunc2();
myFunc3();
myFunc4();
});
In general, it's good practice to keep your functions short and concise.
Also, consider that splitting your code in small units helps you reusing it somewhere else.
Furthermore, you should keep in mind the aspect of testing your code.
It is much easier to test small separate units of code than large chunks.
The point of putting function definitions inside $.ready(), is that those functions become enclosed into that context and not accessible from outside. This can be an advantage (to access enclosed variables or to prevent function misuse), but make it harder to debug.
For my experience, start declaring you functions outside (so you can easily test your code), than move these functions to $.ready().
I want to use an initialization function that will be called after a user visits a part of the application, but after that first visit I don't want to initialize anymore. A simple way to do this is using a flag and an if-statement, but there is a nicer solution to this problem:
in other languages I changed the body of the init function so that after the call of this method.
Can this be done in Javascript too? I wrote something like this, but eclipse says that it is an illegal assignment:
function initEdit(){
...
this = function() {};
}
Yes, you can, but this doesn't refer to the function, so you have to specify it by name:
function initEdit(){
...
initEdit = function() {};
}
Another alternative, that might be easier to follow, is to just use a variable:
var initialised = false;
function initEdit(){
if (!initialised) {
initialised = true;
...
}
}
I have a jquery function like this:
(function($){
$.fn.myjqfunction = function(cfg){
var foo1, foo2;
return this.each...
};
})(jQuery);
How can I make foo1 and foo2 to be accessible from outside (from another function like this)?
These variables will store the state of some things that affect the entire document, and I want the other function to be aware of that...
Declare them outside the function, i.e., global.
You may want to put them in a namespace/object/module to be on the safe side. Which method is best depends on what you're actually doing with them.
For example, if they're related to specific selectors, it might be "best" to attach them directly to the DOM elements using .data, or keep them inside another jQuery function, etc.
Set up your function like this:
(function($){
function myjqfunction( cfg ) {
return this.each( ... );
}
$.myjqfunction = {
foo1: ... ,
foo2: ...
};
$.fn.myjqfunction = myjqfunction;
})(jQuery);
Then from outside your plugin, code can refer to $.myjqfunction.foo1 to get at those variables, and you'd refer to them the same way from inside your plugin code.
There are of course other similar ways to set that up.
I'm working on a proprietary site, and I'm having some issues. I'm using jQuery along with prototype, and I've got it namespaced properly, so in this question assume you can use $ or jQ as a namespaced reference to jQuery.
So I've got a bunch of functions, some mix jQuery and javascript, some plain javascript, some jQuery only. Now, currently some functions are defined within the document.ready jQuery function, and some are defined outside of it, kind of like this:
jQ(document.ready(function($) {
if ( ifConfig ) {
//page check, function calls here
fnc1();
fnc2();
fnc3();
fnc4();
}
function fnc1() {
//fnc code in here
}
function fnc2() {
//fnc code in here
}
}); //end document.ready
function fnc3() {
}
function fnc4() {
}
Now this is all pseudo code, you can assume the functions are valid and have valid code in them. Recently I was doing some debugging, and one of my functions that was declared and called inside the document.ready said it was undefined. I moved it outside of the document.ready, and everything worked again.
I'm basically trying to understand the order of how functions are initiated/called better, so my question is when do you declare functions inside the document.ready and when do you declare them outside? Do you only declare inside when they're called within that document.ready only? Or should I always just declare them outside of that document.ready?
Thanks.
Generally, you should declare & define your own namespace, where all of your application logic (including functions/methods) is located. That way you avoid collision with other scripts on your site + that way your code is much cleaner and easier to maintenaine.
var myapp = function(){
var foobar1 = null,
foobar2 = null,
foobar3 = null;
return {
getFoobar1: function(){
return foobar1;
},
getFoobar2: function(){
return foobar2;
},
setFoobar1: function(foo){
foobar1 = foo;
},
clickhandler: function(e){
alert('I am an event handler, and I am not anonymous');
}
// etc.
};
};
$(document).ready(function(){
var Application = myapp();
Application.getFoobar2();
$(document).bind('click', Application.clickhandler);
});
That pattern (some call it the "method pattern") creates a closured function/object which also guarantees private member variables within your namespace, only accessible through the getter functions from the outside.
This is really only a pretty basic example, you can push this idea & pattern to an extend, which is very nice & a good thing (IMO).
A great book about this stuff which was named and recommended pretty often is "Javascript: The Good Parts" by Douglas Crockford.
If a function is only used inside the document ready function, then declare it inside so you don't pollute the global scope. Otherwise, declare it outside so it the rest of your script has access to those functions.
(document).ready is more used for things that need to be executed at page load, and not function declarations. If you declare them inside of (document).ready, their scope will be local to that block - if they're only used locally, that's fine and they should be declared there. Otherwise, declare them outside.
So in your example, if the functions are only used in that block, they should be declared in there. If they're used other places additionally, they should be declared outside.