Using vanilla javascript, add class to body from within head - javascript

I want to do a quick javascript check from within the head tag, like so:
<html>
<head>
...
<script>
document.body.classList.remove("no-js");
document.body.classList.add("js");
</script>
</head>
<body class='no-js'>
...
</body>
</html>
This doesn't work. Cannot read property classList of null, which...fair enough. If I move the <script> tag into <body>, everything works, but I want the <script> tag in <head>.
What are my options?
EDIT: I should have been much clearer about the error. I realize the problem is that body hasn't loaded when I'm trying to to add the class. However, I was using a bit of Modernizr originally and it was somehow able to modify the body class from within the head and I don't think it was using window.onload or anything like that.

Run the code after body is loaded. There are several approaches to solve the problem:
Move the code into a named function defined in global context and call it in onload.
<html>
<head>
...
<script>
function load() {
document.body.classList.remove("no-js");
document.body.classList.add("js");
}
</script>
</head>
<body onload="load();" class='no-js'>
...
</body>
</html>
Or move code to DOMContentLoaded event listener callback in order to call after dom elements are loaded.
<html>
<head>
...
<script>
document.addEventListener("DOMContentLoaded", function() {
document.body.classList.remove("no-js");
document.body.classList.add("js");
});
</script>
</head>
<body class='no-js'>
...
</body>
</html>
Or move the entire script tag to the end of the page.
<html>
<head>
...
</head>
<body class='no-js'>
...
<script>
document.body.classList.remove("no-js");
document.body.classList.add("js");
</script>
</body>
</html>

At the time the javascript is executed there is no body tag, because the browser hasn't gotten around to it yet. You need to either add the script tag in the body, or add it as an event to execute when the document has loaded. See DOMContentLoaded for an example.

Related

body on load function not getting called if the script tag is end of the body

the code is somewhat like
<body onload="testFunc();">
<div></div>
<script type="text/javascript" src="/js/test.js"></script>
</body>
and the testFunc is inside test.js
and sometimes its not getting called
The onload attribute fires when an object has been loaded.
onload is most often used within the element to execute a script once a web page has completely loaded all content (including images, script files, CSS files, etc.).
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
alert("body loaded");
}
</script>
</head>
<body onload="myFunction()">
<h1>body loaded!</h1>
</body>
</html>

Script tags - not linking (JS platform game)

I'm working through the 'create a platform game' project from Eloquent JavaScript and have an issue with script tags.
In the book we're told to display our level using:
<link rel="stylesheet" href="css/game.css">
<script>
var simpleLevel = new Level(simpleLevelPlan);
var display = new DOMDisplay(document.body, simpleLevel);
</script>
I've tried adding this (together with an additional script tag for my platform.js file) into index.html but the browser is giving nothing back, not sure what I'm doing wrong?
Ensure you are inserting your scripts in the right order:
<!DOCTYPE html>
<html>
<head>
Here you should put your "included" scripts with <script src=...>
</head>
<body>
...
</body>
<script>
Here you should put your first execution, if it needs the html page been completely loaded (as to use document.body).
</script>
</html>
The scripts are being executed as they appear into the page. If you use document, you have to delay the execution until the whole page has been loaded: Either by putting your script at the end of the HTML, either by putting an initialization function within the HEAD, and call it from body onload:
<head>
<script>
function myFunction(){...}
</script>
</head>
<body onload="return myFunction()">
...
</body>
Make sure to include the external JavaScript file you need in a separate <script> tag before your inline script!

How to make Event Listeners work with external Javascript File? [duplicate]

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 9 years ago.
I'm trying to get the element with getElementById(), but it returns null even though the element exists. What am I doing wrong?
<html>
<head>
<title>blah</title>
<script type="text/javascript">
alert(document.getElementById("abc"));
</script>
</head>
<body>
<div id="abc">
</div>
</body>
You have to put this in a document load event. The DOM hasn't gotten to abc by the time the script is executed.
Your script runs before the DOM has been loaded. To fix this you can place your code in the window.onload function like so:
window.onload = function() {
alert(document.getElementById("abc"));
};
An alternative is to place your script right before the closing </body> tag.
If you don't want to attach to the load event then simply put your script at the bottom of the body, so it will execute at the end-
<html>
<head>
<title>blah</title>
</head>
<body>
<div id="abc">
</div>
<script type="text/javascript">
alert(document.getElementById("abc"));
</script>
</body>
</html>
This is because the script runs before the page has rendered.
For proof add this attribute to the body tag:
<body onload="alert(document.getElementById('abc'));" >
But it doesn't exist, not at that point in the HTML. HTML documents are parsed top-to-bottom, just like programs run. The best solution is just to put your script tag at the bottom of the page. You could also attach your JavaScript to the onload event.

JavaScript code in iframe

I need to run JavaScript code in iframe. But script with id "us" loaded after creating iframe. How to run this javascript in iframe?
<iframe id="preview">
#document
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script id="us" type="text/javascript">
$("#preview").ready(function() {
$(".test").click(function() {
alert(true);
});
});
</script>
</head>
<body>
<style></style>
<div class="test"></div>
</body>
</html>
</iframe>
Thanks in advance.
The IFrame has no access to what's outside of it. Everything inside IFrame is separate page ergo you threat it like so. So you do your document.ready in it.
Example: http://jsfiddle.net/ZTJUB/
// Since this is page you wait until it's loaded
$(function() {
$(".test").click(function() {
alert(true);
});
});
The jQuery instance inside of the iFrame doesn't know it's supposed to be traversing the parent DOM, so therefore it won't know where to look for an element with the id "preview"
As per my comments above, you should attach to the iframe's document.ready, like this:
// Since this is page you wait until it's loaded
$(document).ready(function() {
$(".test").click(function() {
alert(true);
});
});
EDIT:
Just realizing you are probably having an entirely different issue here - Html code as IFRAME source rather than a URL - if you are trying to embed the iframe code inline, you are going to have problems. Take the following code for example:
<html>
<head></head>
<body>
Some stuff here
<iframe id="preview">
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script id="us" type="text/javascript">
$(document).ready(function() {
$(".test").click(function() {
alert(true);
});
});
</script>
</head>
<body>
<style></style>
<div class="test">test</div>
</body>
</html>
</iframe>
</body>
</html>
if you render that page in firefox, and then inspect the source in firebug, you'll see:
<html>
<head></head>
<body>
Some stuff here
<iframe id="preview">
<html>
<head></head>
<body></body>
</html>
</iframe>
</body>
</html>
This is happening because the browser isn't expecting to see the code inline between the iframe tags.
Since you're not addressing the questions in the comments to better clarify what you are trying to do... I shall assume you are trying to access content IN your iframe FROM your parent page. Since the other answer should work fine if trying to run it from within the iframe.
On the parent page try something like:
$(function() {
$("#preview").load(function ()
$("#preview").contents().find(".test").click(function() {alert(true);});
});
});
*This assumes both parent and iframe are on the same domain.

Is it possible to define a function in <body> tag of <html> and call it form the <script> tag

I am new to HTML and Javascript, and I have a strange doubt
Is it possible to define a function in "body" tag of html and call it form the "script" tag
Till now i am trying this...
<!DOCTYPE html>
<html>
<head>
<script>
myFunction()
</script>
</head>
<body>
function myFunction()
{
alert("Hello World!");
}
</body>
</html>
No not possible. Browser only understands javascript within the <script> tag.
It will not work, try this,
<html>
<body>
<script>// don't miss script tags for javscript code
function myFunction()
{
alert("Hello World!");
}
</script>
<script>
myFunction(); // call if you have defined function earlier
</script>
</body>
</html>
IMHO:
<html>
<head>
<script>
function myFunction()
{
alert("Hello World!");
}
myFunction();
</script>
</head>
<body>
</body>
</html>
or you can use body Onload.
No U cant do it.....U should put js function within the script tag.....
you can do like this
<!DOCTYPE html>
<html>
<head>
<script>
myFunction();
function myFunction()
{
alert("Hello World!");
}
</script>
</head>
<body>
</body>
</html>
<html>
<head>
</head>
<body>
<script>
function myFunction()
{
alert("Hello World!");
}
myFunction()
</script>
</body>
</html>
I agree with Rohan but just to check I removed the 2nd pair of script tags and called the function in the same script block as it was defined and it worked but this is not normally the way things are done and this is not normally the use of an embedded JavaScript (js)
Doing a little extra research to find the best/optimum place for embedded js appears to be at the bottom of a webpage before the /body (closing body) tag
Here's a link to Yahoo's "speed up your website" guide:
Yahoo! Developer Network: Best Practices for Speeding Up Your Web Site
and here's the text from the page that refers to embedded js:
Put Scripts at the Bottom
tag: javascript
The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.
Also, if you go to the site and click the JavaScript tag you get a whole list of optimisations and tips - refer to the image!

Categories

Resources