Stylesheet ignored when using body onload and document.write - javascript

I am messing around with JavaScript experimenting to get a feel for it and have already hit a problem. Here is my html code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="testing.js"></script>
</head>
<body onload="writeLine()">
</body>
</html>
Here is the JavaScript testing.js:
function writeLine()
{
document.write("Hello World!")
}
Here is the style sheet styles.css:
html, body {
background-color: red;
}
So a very simple example, but I may have chose an awkward example, using on-load in a body tag. So the code above loads and runs the function, but the style sheet does nothing, unless I remove the script tags in the head. I have tried putting the script tags everywhere else, but nothing works. I have researched on-line how to properly link to JavaScript files, and have no found no clear solution, can anyone point out my error?
I have used JavaScript before, but I want a clear understanding from the beginning before I use it any longer

You cannot use document.write after the document is closed (which it will be when onload fires) without destroying the existing document (including links to stylesheets).
Instead, use DOM manipulation, which is covered by chapters 8 and 9 of the W3C JavaScript Core Skills.

Your problem is with the document.write() called in a wrong moment*. This method prints given text at current place in the page as was intended to work while the page still loads. Because you are calling it when the whole page was loaded, the results are unexpected (undefined?)
Instead you should manipulate the dom tree directly:
function writeLine() {
var text = document.createTextNode("Hello World!");
document.body.appendChild(text);
}
Actually in Opera browser I see red background for few milliseconds and then it goes back to white. Try commenting out document.write() - the background is as expected. Moreover you should include <script> tag at the end of body, but this won't solve your problem.
* to be honest, there is no good moment for calling document.write(), avoid it

In your particular example it doesn't matter where the script tag is added as the document.write command executes after the content is rendered, overwriting the existing content.
If you add an alert before overwriting the content you can see your page is red before it gets overwritten with Hello World.

Related

6 javascript tasks assigned to me by my lecturer

I am a complete beginner to javascript. I am also new to this website. I am asking for help to complete an assignment. I have been trying for more than 4 hours by looking at lecture material and online for a solution. It is causing me a lot of unnecessary stress. Before javascript we only used CSS and Html. I was given 6 javascript tasks to manipulate the html file (taskc.html) already given to me.
The tasks are as follows
Make a statement to change contents of h1 from "Welcome" to "Text"
2nd statement should make an new alert window when the page loads that delivers a message explaining what the page is about
3rd statement should change the title to "text"
4th statement should log the contents (innerHTML) of the first paragraph element in the console.
5th statement should hide the contents of the second paragraph when the page loads
6th statement should change the contents of the header to have a new colour of your choice
Here is that html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Task C - The Document Object Mode</title>
</head>
<body>
<h1 id="header">Welcome</h1>
<p id="first">This site uses JavaScript</p>
<p id="second">Javascript is very useful</p>
</body>
</html>
Because the actual coding im meant to add is meant to be in the .js file I was given. so I figured I had to link the js file in the html file so I added
<script type="text/javascript" src="taskc.js"></script>
With that out of the way I went to the lecture notes and I thought I would simply need to modify some of the code given to me there like
document.getElementById('demo').innerHTML = 'Hello World!';
When I put this code in brackets I got the error (document is not defined)
I modified it to match the requirements for task 1
here it is
document.getElementById('header').innerHTML = 'text';
I was confused because I didn't know what this error meant and of course Errors and how to fix them are never explained so I had to lookup how to resolve the error.
I found that to fix it I have to declare it as a variable so I ended up doing this.
var document = 'taskc.html';
When I did this for document, alert and console all the errors went away, but when I did a live preview only statement 1 was working
If anyone could help me fix this I would really appreciate because I don't understand enough javascript to be able to complete this in a reasonable amount of time.
So first: Please use Javascript functions to keep your code tidy and clean.
Example:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Task C - The Document Object Mode</title>
</head>
<body>
<h1 id="header">Welcome</h1>
<p id="first">This site uses JavaScript</p>
<p id="second">Javascript is very useful</p>
<script type="text/javascript" src="taskc.js">test();</script>
</body>
</html>
function test(){
alert("This is a test!");
}
Always implement scripts that are document referenced at the bottom of your html.
If you use JQuery you can use following code to check document is loaded:
$(document).ready(function(){
//foo bar
});

what does "JavaScript sanitization doesn't save you from innerHTML" mean?

I'm learning xss prevention through this ppt:http://stash.github.io/empirejs-2014/#/2/23, and I have a question on this page.
It says "JavaScript sanitization doesn't save you from innerHTML", and I tried a simple test like this:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<div id="test"></div>
<script>
var userName = "Jeremy\x3Cscript\x3Ealert('boom')\x3C/script\x3E";
document.getElementById('test').innerHTML = "<span>"+userName+"</span>";
</script>
</body>
</html>
when I opened this html on my browser(chrome), I only saw the name "Jeremy",by using F12, I saw
<div id="test"><span>Jeremy<script>alert('boom')</script></span></div>
Although the script had been added to html, the alert box didn't come out.
"JavaScript sanitization doesn't save you from innerHTML" I think this means that the word "boom" should be alerted. Am I right?
According to MDN, innerHTML prevents <script> elements from executing directly1, which means your test should not alert anything. However, it does not prevent event handlers from firing later on, which makes the following possible:
var name = "\x3Cimg src=x onerror=alert(1)\x3E";
document.getElementById('test').innerHTML = name; // shows the alert
<div id="test"></div>
(script adapted from the example in the article, with escape sequences although I'm not sure those are relevant outside of <script> elements)
Since <script> elements never execute when inserted via innerHTML, it's not clear to me what that slide is trying to convey with that example.
1 This is actually specified in HTML5. MDN links to a 2008 draft; in the current W3C Recommendation, it's located near the end of section 4.11.1, just before section 4.11.1.1 begins:
Note: When inserted using the document.write() method, script elements execute (typically synchronously), but when inserted using innerHTML and outerHTML attributes, they do not execute at all.

Why scripts at the end of body tag

I know this question was asked many times, but I haven't found answer. So why its recommended to include scripts at the end of body tag for better rendering?
From Udacity course https://www.udacity.com/course/ud884 - rendering starts after DOM and CSSOM are ready. JS is HTML parse blocking and any script starts after CSSOM is ready.
So if we got:
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>CRP</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- content -->
<script src="script.js"></script>
</body>
</html>
CRP would be:
CSSOM ready > JS execute > DOM ready > Rendering
And if script is at head:
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>CRP</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
</head>
<body>
<!-- content -->
</body>
</html>
CRP would be the same:
CSSOM ready > JS execute > DOM ready > Rendering
This question is only about "sync" scripts (without async/defer attribute).
Scripts, historically, blocked additional resources from being downloaded more quickly. By placing them at the bottom, your style, content, and media could download more quickly giving the perception of improved performance.
Further reading: The async and defer attributes.
In my opinion, this is an outdated practice. More recently, the preference is for JavaScript to separate any code that requires the DOM to be present into a "DOMContentLoaded" event listener. This isn't necessarily all logic; lots of code can initialize without access to the complete DOM.
It's true that this causes a small moment when only the script file is being retrieved, and nothing else (for instance, images). This small window can be skipped by adding the async attribute, but even without it I recommend putting script tags in the head so that the browser knows as soon as possible to load them, rather than saving them (and any future JS-initiated requests) for last.
It is a best practice to put JavaScript tags just before the
closing tag rather than in the section of your HTML.
The reason for this is that HTML loads from top to bottom. The head
loads first, then the body, and then everything inside the body. If we
put our JavaScript links in the head section, the entire JavaScript
file will load before loading any of the HTML, which could cause a few
problems.
1.If you have code in your JavaScript that alters HTML as soon as the
JavaScript file loads, there won't actually be any HTML elements
available for it to affect yet, so it will seem as though the
JavaScript code isn't working, and you may get errors.
2.If you have a lot of JavaScript, it can visibly slow the loading of your page
because it loads all of the JavaScript before it loads any of the
HTML. When you place your JavaScript links at the bottom of your HTML
body, it gives the HTML time to load before any of the JavaScript
loads, which can prevent errors, and speed up website response time.
One more thing: While it is best to include your Javascript at the end
of your HTML , putting your Javascript in the of your
HTML doesn't ALWAYS cause errors. When using jQuery, it is common to
put all of your code inside a "document ready" function:
$("document").ready(function(){ // your code here });
This function basically says, don't run any of the code inside until
the document is ready, or fully loaded. This will prevent any errors,
but it can still slow down the loading time of your HTML, which is why
it is still best to include the script after all of the HTML.
Images placed below the script tag will wait to load until the JS script loads. By placing the script tag at the bottom you load images first, giving the appearance of a faster page load.
I think it depends on your website or app. Some web apps are based on JavaScript. Then it does not make sense to include it at the bottom of the page, but load it immediately. If JavaScript just adds some not so important features to some content based page, then better load it at the end. Loading time will almost be the same, but the user will see the important parts earlier (before the page finished loading).
It’s not about a whole site loading faster, but giving a user the impression of some website loading faster.
For example:
This is why Ajax based websites can give a much faster impression. The interface is always the same. Just some content parts will alter.
This was an extremely useful link. For any given webpage, a document object model is created from the .html. A CSS object model is also created from .css.
We also know that JS files also modify objects. When the browser encounters a tag, the creation of DOM and CSS object models are immediately halted when the script is run because it can edit everything. As a result, if the js file needed to extract information from either of the trees (DOM and CSS object model), it would not have enough information.
Therefore, script srces are generally at the end of the body where most of the trees have already been rendered.
Not sure if this helps,
But from this resource script-tag-in-web the inline script is always render blocking even if kept at the end of body tag.
Below inline script is first render blocking.Browser will not paint anything on screen till the long for loop is executed
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path: Script</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script>
let word = 0
for(let i =0; i<3045320332; i++){
word += i;
}
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = word + 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
</script>
</body>
</html>
But'index.js' below is not initial render blocking, the screen will be painted , then once external 'index.js' is finished running the span tag will be updated.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path: Script</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script type="text/javascript" src="./index.js">
</script>
</body>
</html>
index.js
let word = 0
for(let i =0; i<3045320332; i++){
word += i;
}
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = word + 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);

Replace complete HTML document with HTML code containing inline scripts

I have the following code which works properly in chome
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
//<![CDATA[
!function (){
window.stop();
var html = '<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n</head>\n<body>\n \<script>console.log("loaded");<\/script>\ntext\n</body>\n</html>';
document.documentElement.innerHTML = html;
}();
//]]>
</script>
</body>
</html>
It prints "loaded" in the console. The same code does not work by firefox, it does not run the script, just prints the text.
(If you are curious why I need this, you can find it here: https://stackoverflow.com/a/30933972/607033 )
I tried possible solutions like this: https://stackoverflow.com/a/20584396/607033 but they did not work. Any idea how to work this around?
Note: there are many scripts in the HTML, e.g. bootstrap, jquery, facebook, google, etc..., not just a single inline script.
I think there is no way in firefox to replace the complete HTML document with javascript without leaving the actual page. A workaround to reuse the original document and replace only the head and body tags:
$('html').html(html);
does this automatically: it strips out the HTML tags, injects the head and the body and loads the scripts.
ref: https://stackoverflow.com/a/1236372/607033

jQuery.html() removes scripts and styles

Is there a way to use jQuery.html() and not loose the scripts and styles? or any other non-jQuery way?
I'm trying to output the full HTML of the page the user is on. Is this even possible?
jQuery.html() removes scripts and styles
That isn't my experience (see below). In practice, you have to be aware that what you get back by querying the DOM for HTML strings is always going to be the interpreted HTML, not the original, and there will be quirks (for instance, on IE all the HTML tag names are IN UPPER CASE). This is because jQuery's html function relies on the browser's innerHTML property, which varies slightly browser to browser. But the demo below includes both style and script tags on Chrome 4, IE7, and Firefox 3.6; I haven't tried others, but I would expect them to be okay.
If you want to get the content of externally-linked pages as well as the inline content, you will naturally have to parse the result and follow the src (on scripts), href (on links that have rel = "stylesheet"), etc...
Demo:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>
<script type='text/javascript'>
(function() {
$(document).ready(pageInit);
function pageInit() {
$('#btnGo').click(go);
}
function go() {
alert($('html').html());
}
})();
</script>
</head>
<body>
<input type='button' id='btnGo' value='Go'>
</body>
</html>
I see 2 scenarios here
you use jQuery.html(yourHTML) to overwrite the entire html of the page, so even the script tags were overwritten...
you use jQuery.html() to retrieve the entire document html. if this is the case you need tu ensure that the element on which .html() function is used, is the entire html... as T.J. Crowder suggested $('html').html()

Categories