I'm having problems with global variables.
Considering that I have the following files: init.html, main.html, init.js, main.js and help.js :
Where, init.html:
<HTML>
<HEAD>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript" charset="UTF-8" src="init.js" ></script>
<script type="text/javascript" charset="UTF-8" src="main.js" ></script>
<script type="text/javascript" charset="UTF-8" src="help.js" ></script>
</HEAD>
<BODY>
<script>
$(document).ready(function() {
test();
});
</script>
</BODY>
</HTML>
In init.js :
function test(){
alert(window.glob);
}
In main.html :
<HTML>
<HEAD>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"> </script>
<script type='text/javascript' >
top.glob = "global variable";
</script>
<script type="text/javascript" charset="UTF-8" src="help.js" ></script>
<script type="text/javascript" charset="UTF-8" src="main.js" ></script>
</HEAD>
<BODY>
<div id="divtest"></div>
<form>
<input type="button" value="button" onClick="callTest()" />
</form>
</BODY>
</HTML>
main.js:
function change(p){
window.glob = p;
$('#divtest').html("<iframe id='IFRAMEtest' width='720' height='400' frameborder='0' src='init.html'></iframe>");
}
And in help.js :
function callTest(){
change('param');
}
When I click in button, displays "global variable", but I need to display "param".
In short, I need that a .js file read a global variable in another js file where this variable is fed into a function called by an event of a user.
Thanks.
edit - initialized global variable before importing files. js and using top. Works in IE and firefox, but chrome display "undefined"
Take a look here:
Global variables in Javascript across multiple files
The main thing is, that you may have to declare the global variables
before the actual file, so try inserting this before your inclusion to help.js
so try giving this a shot.
<script type='text/javascript' >
window.glob = "global variable";
</script>
so your code should be:
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js" ></script>
<script type='text/javascript' >
window.glob = "global variable";
</script>
<script type="text/javascript" charset="UTF-8" src="help.js" ></script>
<script type="text/javascript" charset="UTF-8" src="main.js" ></script>
</head>
try that and see if it works.
also, remove your global variable declaration from main.js for this.
There's no global context that spans windows (frames), really. All frames in a "family" have access to a variable called "top" that refers to the topmost window, so you could use that.
top.glob = "global variable";
and in your iframe code:
function test(){
alert(top.glob);
}
edit — Here is a a slightly simplified version of your code, and it works fine for me.
When you are inside a frame and want to get a window variable from the parent window, you must refer to it.
Use top or window.top.
Related
I'd like to define a Webcomponent in a Javascript-Module and call a method of this component.
The browser raises an Javascript-error: "helloworld" is not a function.
Strange: If I load the Javascript-File "normally" and not as a module, the function is called.
How can I make it run as a Javascript-Module?
This is the JavaScript-Module main.js:
customElements.define('hello-world',
class MyComponent extends HTMLElement {
helloworld() {
console.log("Hello World");
}
});
This is the HTML-Code:
<!DOCTYPE html>
<html>
<head>
<script type="module" src="main.js"></script>
</head>
<body>
<hello-world></hello-world>
<script>
var instance = document.querySelector( 'hello-world' );
instance.helloworld();
</script>
</body>
</html>
Loading Javascript with
<script src="main.js"></script>
works.
Problem is: Modules are alway loaded asyc and are alway executed after the DOM is loaded.
Therefore the Web-Component is not yet defined when it's instanciated in HTML.
This code works, since the inline-module is executed after the extern module.
<!DOCTYPE html>
<html>
<head>
<title>simple demo</title>
<script type="module" src="main.js"></script>
</head>
<body>
<hello-world></hello-world>
<script type="module" >
var instance = document.querySelector('hello-world');
instance.helloworld();
</script>
</body>
</html>
I looked at this and this answer to that question, but they only get the HTML contents of the page up until the <script> that executes the code.
For example, in this snippet:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript">
console.log(new XMLSerializer().serializeToString(document));
</script>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<script type="text/javascript" src="testscript1.js"></script>
<script type="text/javascript" src="testscript2.js"></script>
<script type="text/javascript" src="testscript3.js"></script>
</body>
</html>
if you take a look at the console.log() and scroll past the stackoverflow stuff, you'll see:
<script type="text/javascript">
console.log(new XMLSerializer().serializeToString(document));
</script></body></html>
the <script> with src="testscript1.js" and the other two <script> tags are not present, I.E. the logged string does not contain all the HTML.
If you put the logging script at the bottom like this:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<script type="text/javascript" src="testscript1.js"></script>
<script type="text/javascript" src="testscript2.js"></script>
<script type="text/javascript" src="testscript3.js"></script>
<script type="text/javascript">
console.log(new XMLSerializer().serializeToString(document));
</script>
</body>
</html>
it logs the other <script> tags.
Question
My guess is that since my scripts are loaded synchronously, the log outputs whatever has been loaded up to this point. How could I avoid that? I want my logging <script> to be as close to the top of the HTML as possible, while having access to all the HTML content.
What I've tried
If I put this script in the <head>:
var req = new XMLHttpRequest();
req.open("GET", document.location.href + "index.html", false);
req.onreadystatechange = function () {
if (req.readyState === 4) {
if (req.status === 200 || req.status == 0) {
console.log(req.responseText);
}
}
}
req.send(null);
I get the desired result. But I don't like how easily it could fail. For example, if I paste this code as a snippet here in stackoverflow, it doesn't work because the requested file doesn't exist. If the document is named notindex.html, it would fail too.
Are there any alternatives or a reliable way to request the opened HTML document via an XMLHttpRequest?
Edit
I want to have access to all the HTML content before all stylesheets, scripts and images have loaded. That's the reason I want the logging script to be at the top. The XMLHttpRequest does it, but is unreliable.
You can use the DOMContentLoaded event to run the function after your document has completely loaded:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
console.log(new XMLSerializer().serializeToString(document));
});
</script>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<script type="text/javascript" src="testscript1.js"></script>
<script type="text/javascript" src="testscript2.js"></script>
<script type="text/javascript" src="testscript3.js"></script>
</body>
</html>
I have one file, that is external from my index.html page, named code.js with this code on it:
function parse() {
if (a === 1)
alert("a equals 1");
}
(function() {
parse();
})();
As I said, that file is called code.js.
Now, I have an index.html file that is in the same folder/directory as the code.js file. Now, this is my index.html:
<!DOCTYPE html>
<html>
<head>
<title>Javascript</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="code.js"></script>
<script type="text/javascript">
var a = 1;
</script>
</head>
<body>
<h1>Javascript</h1>
</body>
</html>
So I want to be able for the code.js file to use the variable from my javascript that is in the index.html file. I am doing this because I am going to make my own javascript library, but I need to do learn this first. Any solutions?
Switch the order of your script tags:
<script type="text/javascript">
var a = 1;
</script>
<script src="code.js"></script>
This way, the global variable a will be initialized before the parse method in code.js is called.
To add on to what Robby said, browsers load a page in order from top to bottom, left to right, because that is how they are written (sort of). This means in your supplied code, code.js is loaded and run before you set a=1. As Robby mentioned, you can easily switch the order of your <script> tags and be fine.
This applies to other elements as well, so any other elements will not be accessible before their place in the HTML document. For example, a <div> in the body cannot be referenced by code run in the head, because the body has not been loaded yet. You can circumvent this by adding a <script> tag at the end of your HTML document, to be run after the main document has been loaded, but not necessarily all other external data like images (external scripts should be fine, however). The snippet below is what I have found works best:
<!DOCTYPE html>
<html>
<head>
<title>Javascript</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<!-- Any script here could be anywhere (embedded/external) and in any order -->
<script>
function ready() {
document.getElementById('a').textContent = 'a = ' + a;
}
</script>
<script type="text/javascript">
var a = 1;
</script>
<!-- <script src="code.js"></script> - load external code here -->
</head>
<body>
<h1>Javascript</h1>
<div id="a">a = ?</div>
<script>ready(); // Runs code after document is initialized</script>
</body>
</html>
In the javascript assets file I have a jstester.js file like this:
function hehe()
{
alert("wedsdsd");
}
document.write("fdygsdfysdgf");
Then in the public index.html file I have this:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script src="/assets/jstester.js">
hehe();
</script>
</body>
</html>
So I thought that is how I can call a method from my Javascript file but looks like it is not working, no message box shows up... So what is the correct way of doing this?
If a <script> has a src then the text content of the element will be ignored.
so you can't do:
<script type="text/javascript" src="assets/jstester.js">
hehe();
</script>
but:
<script type="text/javascript" src="assets/jstester.js"></script>
<script>hehe();</script>
This is what you looking for:
<body>
<script src="/assets/jstester.js"></script>
<script type="text/javascript">hehe();</script>
</body>
I have a jQuery library code in jquery.xyz.js .
I have an html file which uses the function defined in jquery.xyz.js in this manner .
<html>
<body>
<script type="text/javascript">
document.write("This is my first JavaScript!");
$(function(){ $("ul#xy01").xyz(); });
</script>
</body>
</html>
But the jQuery is not running, which I am assuming because I haven't loaded the jQuery properly onto the html page. So how do I do it?
<script type="text/javascript" src="jquery.js"></script>
See how jQuery works in the manual for the basics, and the download page to fetch the library (or to find out addresses for direct linking on a Content Delivery Network).
You just need to include the script files before using functions defined in them ($ is just a function), for example:
<html>
<body>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.xyz.js"></script>
<script type="text/javascript">
$(function(){ $("ul#xy01").xyz(); });
</script>
</body>
</html>
Be sure to include jQuery before plugins that rely on it, or you'll get some errors first thing.
<script>
var script = document.createElement('script');
script.onload = function () {
//do stuff with the script
};
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/xx.xx/jquery.min.js';
document.head.appendChild(script);
</script>
<script type="text/javascript" src="PATH TO YOUR JS FILE"></script>
Stick this above your jQuery code in the <head></head>
<script src="/js/jquery.js" type="text/javascript"></script>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js">
</script>
</head>
<body>
<script type="text/javascript">
document.write("This is my first JavaScript!");
$(function(){ $("ul#xy01").xyz(); });
</script>
</body>
</html>