In my main Web Page (Viewer.aspx) I have a javascript script tag like this
<script language="javascript" type="text/javascript">
function initialize() {
var map = $find('Map1');
map.add_mouseMove(mouseMove);
}
</script>
Within those script tags I have a function. Is it possible to call another function that is in a different script tag like this?
<script language="javascript" type="text/javascript" src="Resources/JavaScript/proj4js-combined.js">
function mouseMove(sender,eventArgs) {
var source = new Proj4js.Proj('EPSG:3116');
var dest = new Proj4js.Proj('WGS84');
var p = new Proj4js.Point(px, py);
Proj4js.transform(source, dest, p);
}
</script>
Yes, this is done quite regularly as Javascript functions can be put into other files and pulled into pages that work this way.
Your second script tag specifies a src. The contents of the .js file will be loaded and parsed, but the code inside the script tag (the mouseMove function) will be ignored. If you want both the function and the contents of the .js file, you need to separate them into two different script tags.
As per your comment, here's what T.J. was talking about - you need to turn your second script block into something like this:
<script type="application/javascript" src="Resources/JavaScript/proj4js-combined.js"></script>
<script type="application/javascript">
function mouseMove(sender,eventArgs) {
var source = new Proj4js.Proj('EPSG:3116');
var dest = new Proj4js.Proj('WGS84');
var p = new Proj4js.Point(px, py);
Proj4js.transform(source, dest, p);
}
</script>
...but you should really just move the inline code block (what's inside of the 2nd <script> tag in my answer) to an external Javascript file.
Edit 1: What's the programming background you're coming from? If it's something like C# or Java, you'll need to forget what you know about those and approach Javascript completely differently. Javascript is an interpreted language, not a compiled one; among other things, this means that the order in which your functions are declared matters.
When I say "function declaration," I mean anything that looks like this:
function myNewFunction()
{
// anything else here
}
This tells the Javascript interpreter about a new function, called myNewFunction, whose body consists of whatever is in the curly braces.
Here's an example of what I'm talking about when I say you are using a function before you've declared it. Consider the following block of code (in isolation from any other Javascript, say, in an external Javascript file):
function foo() // this line declares the function called "foo"
{
}
function bar() // this line declares the function called "bar"
{
foo(); // this line invokes the previously declared function called "foo"
}
This will work as expected, because foo() was declared before you called it. However, what (it sounds like) you're trying to do is analogous to this:
function foo() // this line declares the function called "foo"
{
bar(); // this line tries to invoke the function called "bar"
// but it hasn't been declared yet! so it's undefined
}
function bar() // this line declares the function called "bar"
{
}
If you were to run this second Javascript snippet, it wouldn't work, because you're calling a function before it was declared.*
*Footnote: this is not actually the case, because using this syntax (function foo() { ... }) does something special and magical in Javascript. My particular example will actually work, but it illustrates the problem you're having.
Related
I'm having some issues with running some functions from an external js file.
The html includes:
<script src="js/file.js"></script>
<script>
$("#center-button").click(function() {
explodePage("center");
});
</script>
The js file includes:
var explodePage = function(button) {
//code here
aboutPage();
}
var aboutPage = function() {
//code here
}
The explodePage function runs fine, but as soon as it reaches the call to the nested aboutPage function, it starts throwing these uncaught typeerrors at me. It works fine if I don't use an external js file and just put everything into the html. Pretty new to this so probably missing something obvious in scope or something. Any solutions?
Declare the function's definition as below:
function explodePage(button) {
//code here
aboutPage();
}
function aboutPage() {
//code here
}
Explanation:
When you use the var keyword for declaring functions, the execution of JS happens as when the variable is initialized, you cannot reference or use variable's before declaration. In contrast with the name function defintion JS interpreter first picks the enclosed functions before execution and initializes it before the code execution. This is called AST- Abstract syntax tree that is followed by JS interpreters.
Also Remember:
Also bind your Jquery code inside a Jquery document ready function, just to make sure the Jquery and the DOM elements are available for the bindings.
It's not a good a idea to pollute the global window object with variables, since there can be collisions. And immediately-invoked function expression is a good solution for this.
(function(){
//You can declare your functions in here, and invoke them below
$( document ).ready(function() {
//Check that the DOM is ready, in order to manipulate it an add events
$("#center-button").click(function() {
explodePage("center");
});
});
})($); //Notice that we are injecting a dependency, in this case jQuery
This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 6 years ago.
<!DOCTYPE html>
<html>
<body onload="myFunction()">
<script>
var go="globle";
function myFunction() {
var go="local";
document.write(go);
}
document.write(go);
</script>
</body>
</html>
when I run this code it will print local.But when I run the following code:
<!DOCTYPE html>
<html>
<body onload="myFunction()">
<script>
var go="globle";
function myFunction() {
var go="local";
}
document.write(go);
</script>
</body>
</html>
This code print globle.
Why not the first code printing both local and globle.
And also when I run first code my html body is also not executed.
You are using document.write, which deletes everything when called.
The write() method is mostly used for testing: If it is used after an
HTML document is fully loaded, it will delete all existing HTML.
Change it console.log(go) and you will see the expected output.
Your first example is flawed because of the use of document.write. When you use that AFTER a document has been built, it wipes out the earlier document and writes a new one. The results you were seeing from the first example were distorted by this.
Really, your examples are just demonstrating Global vs. Function scope in JavaScript. Anything declared with var in a function has local scope to that function and will be removed from memory when the function it is declared within terminates or is no longer held in memory.
Take a look at the comments I've added to your slightly modified code:
// We are going to replace all the document.write() calls with
// console.log() calls because you are experiencing information being
// written to the document and then the document is being overwritten
// with new information.
// The result will be "global, local" because the code in "myFunction" is
// not going to run until the window is loaded. The last line of code in
// this example will actually run first.
window.onload = myFunction;
var go="global"; // Just declare a Global variable (available everywhere)
function myFunction() {
// Declare a local variable, available only in the function
// Since this variable uses the same name as the global one
// when this function is executing, this variable will override
// (hide) the other one.
var go= "local";
console.log(go); // The local one is used
}
// Now, we are outside the function and the local version of "go" is
// out of scope. It's gone and can't be accessed. But, the global version
// is still available
console.log(go); // The global one is used
Here's your second example:
// Again, we're replacing document.write with console.log
// Even though we're calling the "myFunction" function when the
// window is loaded, that function only sets a local variable
// that will be destroyed when the function ends. It never does
// anything with that variable.
window.onload = myFunction;
var go="global";
function myFunction() {
// This will be destroyed as soon as the function is done
// which is the line right after it gets declared!
var go="local";
}
// Again, the scope of this line of code is global and so the global value is used
console.log(go);
I have a trouble to call a function in another file while inside second file the called function have to call another function in first file. How it is possible?
In my example I first call Printer1 function which is in File2.js then in File2.js I call Printer2 which is declared in File1.js (but I didn't include File1.js in File2.js. but I do it in the File1.js (Including File2.js)
File1.js
var data1="Hi";
Printer1(data1);
var Printer2(){
document.write(data1);
}
File2.js:
var Printer(data1){
document.write(data1);
Printer2();
}
Also I want to know if I can include the File2.js at the beginning of the page or I have to include one line before I call Printer1?
Your javascript is going to be executed in the order it is loaded, other than hoisting, where functions can be used before they are written if you use the right syntax.
File 1:
function foo() {
alert("I'm foo!");
}
File 2:
foo(); //alerts "I'm Foo!"
Basically, having two files like
Is the same as combining them and just including them together. If it works like that, it will work seperately as well, other than hoisting.
This is how hoisting works: (this must be in the same file and in the same scope)
foo(); //alerts "I'm foo!" even though we haven't told it to yet.
function foo() {
alert("I'm foo!");
}
This works because functions defined that way will be "hoisted" to the beginning of the execution in that scope.
What WON'T work:
foo(); //undefined!!
var foo = function() { //doesn't get hoisted!
alert("I'm foo!");
}
If you want hoisting, use the other syntax!
One thing you might be wondering is this, but I can't really figure out your question (confusing wording, lol)
What if file 1 has a function that uses a function from file 2?
In that case, you won't be able to use the function in file 1, because the function from file 2 will be undefined at the time file 1 is executed, but you CAN use the file 1 function in file 2 (even at the beginning if you have it hoisted).
Like this:
File 1:
function foo() {
bar();
}
foo(); //bar is undefined! error!
File 2:
foo(); //works!! bar is hoisted and therefore defined already for "foo" to use
function bar() {
alert('from file 2!');
}
First off you have var where you should have function. You shouldn't use document.write either. Check this out. The JS should look like:
file1.js:
var data1="Hi";
Printer1(data1);
function Printer2(){
document.write(data1);
}
file2.js
function Printer1(data1){
document.write(data1);
Printer2();
}
And in order to make the function in file2 be callable you need your markup to look like this:
<body>
<script type="text/javascript" src="file2.js"></script>
<script type="text/javascript" src="file1.js"></script>
</body>
The Google Analytics tracking code looks like this:
(function() {
code
})();
What's the technique they are using with those brackets - (stuff)() - called? What does it do?
I put the Google Analytics code before the closing head tag on my page and then put an if statement around it like this (I include a Jquery cookie plugin further up):
<script type="application/javascript">
if ($.cookie('allowcookies') == 'yes') {
analytics code
}
</script>
It didn't run until I used the same technique around my code:
(function() {if ($.cookie('allowcookies') == 'yes') {
analytics code
}
})();
Why did it not run before I did that? Why did it run after?
(function() {
/* code */
}());
It's commonly known as «self executed anonymous function (¹)» (o «immediate function invocation») and its main use is to avoid the creation of variables into the global (or in the outer) scope.
It's also used as shortcut when you want to create a function to execute just once, without the need to first define the function with its own identifier and then soon make the function call.
It may be eventually used inside a scope and then it may create a closure if the outer context (or other references) are binded through parameters passing, e.g.
/* outer scope */
(function(outerscope) {
element.onsomeevent = function() {
/* do something with outerscope */
};
}(this));
Another practical use I make with this expression is when I need to create a function to be soon executed inside a constructor function when it is called with new keyword (instead of an explicit call to some init method).
(¹) — as stated on book "Mantainable Javascript" by Nicholas Zakas (O'Reilly, ISBN 978-1-449-32768-2) page 44, the suggested expression is (function() {}()), with nested parens (even if (function() {})() will work anyway)
[...]To make it obvious that immediate function invocation is taking place, put paretheses around the function[...]
See also Immediate function invocation syntax
The "function(){code}" part only creates a function, the () at the end call the created function.
You could rewrite
(function() {
code
})();
As
var x = function() {code};
x();
It's just a select calling function. The () at the end causes it to be called automatically.
It's used like this to isolate local variables that are relevant only to your code from the global scope.
For example:
(function() {
var x = 5;
window.y = 6;
})();
x is available only in the scope of the function, y is globally available through the window.
As to it not running, I'd hazard that's down to the conditional you supplied.
Lets say this function...
function foo(param){
// original works
}
is already in-place in an html document.
I have a bookmarklet that injects an external script to the document. From that script, I want to modify the behavior of foo() function into this...
function foo(param){
// original works
bar(param);
}
bar() is a new function in the injected script.
I have no problem duplicating foo in the injected script.
How do I do this?
Everything in javascript can be an object, including functions. With this in mind, you can create a duplicate of the old function, then override the new one while referencing the duplicate:
function foo(param){
// original works
}
var old_foo = foo;
function foo(param) {
old_foo(param);
bar(param);
}