Get HTML document as string before it has loaded - javascript

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>

Related

Javascript shows me TypeError saying my variable is undefined

Im trying to code a simple Javascript exercise where I have to place different text at different part of the page but it keeps throwing me a
TypeError:sal[0] is undefined
Here is the javascript code.
function sals(a,b,c,d,e,id)
{
var sal = document.getElementsByClassName(id);
sal[0].style.top=a;
sal[0].style.left=b;
sal[0].style.color=c;
sal[0].style.fontsize=d;
sal[0].style.zindex=e;
}
sals('5%','50%','yellow','250px','20','GB');
What am I doing wrong?
For further reference, here is my HTML code aswell
<html>
<head>
<title>Hello</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<h1 class="GB"> Holla</h1>
<script src="main.js"></script>
</body>
</html>
Your JavaScript is running before the page (DOM) has fully loaded.
the simplest way to make sure the DOM is loaded before your JS runs, is to add 'defer' to the script tag thus;-
<head>
<title>Hello</title>
<link rel="stylesheet" href="main.css">
<script src="main.js" defer></script>
</head>
<body>
<h1 class="GB"> Holla</h1>
</body>
</html>

Checking a variable in js that is directly in html file

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>

jQuery click not fired

I have this simple html file with little bit of jQuery in it but click event is not triggered here:
I am not getting any error and neither the console.log statement that I expect to print when click event is triggered.
Did I miss out on something?
<!doctype html>
<html>
<head>
<title>My WebPage</title>
<link rel="stylesheet" type="text/css" href="Day.css"/>
<link rel="stylesheet" type="text/css" href="Night.css"/>
</head>
<body>
<h1> My website </h1>
<button>Day</button>
<button>Night</button>
<script src="jquery.js"/>
<script>
(function(){
console.log('Inside func');
$('button').click(function() {
console.log('button was clicked');
});
})();
</script>
</body>
</html>
<script src="jquery.js"/>
should become:
<script src="jquery.js"></script>
You can read more about self-closing script tags here: Why don't self-closing script tags work?
I would just use the JQuery CDN in the head section.
Here's a demo

Why is body onload not working in chrome

I'm encountering a problem where my body onload="constructor()" is not being run. It works fine for me in firefox but I don't understand why it's not working for me in chrome. Here's the code I'm working with, I made a separate file and deleted everything to the bare minium to try figure out what was going wrong:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Personality Font</title>
<link rel="stylesheet" type="text/css" href="p1.css" />
<script type="text/javascript" src="data.js"></script>
<script type="text/javascript">
//<![CDATA[
function constructor(which)
{
console.log("IN CONSTRUCTOR"); //In Constructor
var text = document.createElement('p');
text.appendChild(document.createTextNode("BLAH"));
document.getElementsByTagName('body')[0].appendChild(text);
}
//]]>
</script>
</head>
<body onload = "constructor();">
<h1>Personal Fonts: Find the Typeface that Matches Your Personality</h1>
<form>
</form>
</body>
</html>
Chrome has a built-in function with the name constructor. Call the function something else.

Javascript: Global variables shared between .js files

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.

Categories