This is an error in Firebug I keep seeing.
TypeError: $("#gallery-nav-button") is null
[Break On This Error]
$('#gallery-nav-button').addClass('animated fadeOutRightBig');
Here is my code:
JS
$(function() {
$("#close-gallery-nav-button").click(function() {
$('#gallery-nav-button').addClass('animated fadeOutRightBig');
});
});
HTML
<div id="gallery-nav-button">
<h4 id="close-gallery-nav-button">X</h4>
<h3 class="text-center small-text"><a class="inline text-center small-text" href="#gallery-nav-instruct">Click Here for Gallery <br /> Navigation Instructions.</a></h3>
</div>
CSS
#close-gallery-nav-button{
text-indent:-9999px;
width:20px;
height:20px;
position:absolute;
top:-20px;
background:url(/images/controls.png) no-repeat 0 0;
}
#close-gallery-nav-button{background-position:-50px 0px; right:0;}
#close-gallery-nav-button:hover{background-position:-50px -25px;}
I also want to add - because this is the #1 Google search result for the important error message "TypeError: [x] is null" - that the most common reason a JavaScript developer will get this is that they are trying to assign an event handler to a DOM element, but the DOM element hasn't been created yet.
Code is basically run from top to bottom. Most devs put their JavaScript in the head of their HTML file. The browser has received the HTML, CSS and JavaScript from the server; is "executing"/rendering the Web page; and is executing the JavaScript, but it hasn't gotten further down the HTML file to "execute"/render the HTML.
To handle this, you need to introduce a delay before your JavaScript is executed, like putting it inside a function that isn't called until the browser has "executed" all of the HTML and fires the event "DOM ready."
With raw JavaScript, use window.onload:
window.onload=function() {
/*your code here*
/*var date = document.getElementById("date");
/*alert(date);
}
With jQuery, use document ready:
$(document).ready(function() {
/*your code here*
/*var date = document.getElementById("date");
/*alert(date);
});
This way, your JavaScript won't run until the browser has built the DOM, the HTML element exists (not null :-) ) and your JavaScript can find it and attach an event handler to it.
I have several scripts running on this page and evidently one script was conflicting with another. To solve my issue I added jQuery.noConflict();
var $j = jQuery.noConflict();
$j(function() {
$j("#close-gallery-nav-button").click(function() {
$j('#gallery-nav-button').addClass('animated fadeOutRightBig');
});
});
As additional comment on #1 solution:
Another possibility for loading the script after finishing/building the HTML should be placing a defer parameter inside the script tag:
<script defer type="text/javascript" src="x.js"></script>
I agree with the advice given above, relating to the onload event. https://stackoverflow.com/a/18470043/2115934
A more simple solution (though not necessarily a better one) is to put your script tag just before the closing body tag of the document.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1></h1>
<p></p>
<script src="script.js" type="text/javascript"></script> <!-- PUT IT HERE -->
</body>
</html>
I know this has been answered and it is an old post but wanted to share my experience. I was having the hardest time getting my code to load and was getting this error constantly. I had my javascript external page loading in the head section. Once I moved it to just before the body ended the function fired up right away.
Related
My goal is to load javascript in the <head> only if a certain element exists in the <body>.
However, I have a problem: I am loading a Web Component, which is just a <script> hosted elsewhere and is pulled in as:
<script src="https://someurl.com/some-web-component.min.js"></script>
This web component file is huge, so I don't want to pull it in unless it is inserted into body by our Content Management System (CMS).
The constraints I am working under are:
• The <head> is shared between pages, so I need conditional logic
• I have no control over the <body> inserted by the CMS, which will potentially contain the <my-web-component> tag
• I NEED the script to load the web component, so I can't use jQuery's $(document).ready, at least I think I can't - an error will be thrown because the browser won't know the element exists
This plunker partially shows my problem, minus all the web component complexity:
https://plnkr.co/edit/GGif2RNHX1iLAvSk1nUw?utm_source=next&utm_medium=banner&utm_campaign=next&p=preview
Any way around this?
You can use DOMContentLoaded event.
The DOMContentLoaded event is fired when the initial HTML document has
been completely loaded and parsed, without waiting for stylesheets,
images, and subframes to finish loading.
In this case you can look for the Component and add the script with something like the following
document.addEventListener("DOMContentLoaded", function(event) {
if(document.querySelector('Component')){
var script = document.createElement('script');
script.src = 'https://someurl.com/some-web-component.min.js';
document.head.appendChild(script)
}
});
Probably a better approach though would be to add the script in the head with async attribute and later remove it if the component is not found.
Something like this
<script async src = "https://someurl.com/some-web-component.min.js"> </script>
<script >
document.addEventListener("DOMContentLoaded", function(event) {
if (document.querySelector('Component') == null) {
var script = document.querySelector('script[src="https://someurl.com/some-web-component.min.js"]')
document.head.removeChild(script)
}
});
</script>
More about DOM lifecycle events
More about async script loading
I am using $(document).ready and inside this method checking if element exists or not. It is working completely fine for me. Below is code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery Test Element Exists or Not</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var elem = document.querySelector('h1');
var isElemPresent = !!elem;
console.log('Is the element present: ', isElemPresent);
});
</script>
</head>
<body>
<h1>Hello Plunker!</h1>
<script>
var elem = document.querySelector('h1');
var isElemPresent = !!elem;
console.log('Oh NOW it works...: ', isElemPresent);
</script>
</body>
</html>
I am not sure where you are facing issue while using jQuery. There might be some other issue. Above approach is good enough to load script after checking if element is present.
Plunker link:
https://run.plnkr.co/preview/cjgczwlzt000knneldv5d52ea/
I have tried finding an answer to this on my own, but only found instructions on how to use onload events. I seem to be missing the point.
I've been taught that if I want something to happen when the page loads, I should use window.onload like this:
<script>
window.onload = dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
But now that I am thinking on my own I wonder what the point of doing that is. Because this also produces the same result:
<script>
dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
Anything I put at the top inside <script> is going to execute anyway... so what's the point of window.onload?
If you're directly running your code with dosomething();, you're delaying your browser's rendering for the time it takes your JavaScript code to run.
You can try to insert your code to the <head> of your html document:
<!DOCTYPE html>
<html>
<head>
<script>
dosomething();
function dosomething()
{
window.alert('hello');
}
</script>
</head>
<body>
Does not render before the alert is dismissed!
</body>
</html>
You'll see that the page stays blank until you dismiss the alert. So every second the browser takes to run your JavaScript code is a second that your users have to wait for the site to be rendered.
Now if you change the code to be run on body's onload, the page gets rendered before the alert is shown:
<!doctype html>
<html>
<head>
<script>
function dosomething()
{
window.alert('hello');
}
</script>
</head>
<body onload="dosomething()">
This page gets rendered before the alert!
</body>
</html>
Consider these two blocks of code:
<head>
<script>
alert(document.getElementById('foo').value);
</script>
</head>
<body>
<input id="foo" value="hello">
</body>
<head>
<script>
window.onload = function() {
alert(document.getElementById('foo').value);
}
</script>
</head>
<body>
<input id="foo" value="hello">
</body>
In the first example, we'll get an error because the element you are referencing isn't found when the script runs - and so you are trying to get value of null.
In the second example, document.getElementById() will find the element with the id foo, because window.onload will get fired only when the complete DOM has been loaded and so the element is available.
window.onload will fire once the DOM has finished loading. In your example, the DOM is not required. However, the following code will fail if the DOM has not yet loaded:
function doSomething() {
alert(document.getElementById('test').innerText);
}
// Throws: TypeError: Cannot read property 'innerText' of null
Assuming your page contains an element with id test, it will alert its text.
waiting for the onload event assures you that all of your scripts and resources are loaded
Assume you are using jquery in your page and you invoked a function that uses it directly without onload , you can't guarantee that the jquery file has been loaded, which will lead to errors and possibly ruining your whole logic
The onload event is handy to make sure the page is fully loaded before you run a script. For your example above it doesn't make sense, but if your page is still loading an item on the bottom and you try to call it then nothing will run.
I recommend using jQuery and using the ready function. This way you will ensure your page is completely loaded.
$( document ).ready(function() {
// This will only run after the whole page is loaded.
});
If you don't want to load query, just put your javascript at the bottom of the page. It's best practice, and ensures the DOM is loaded in full.
For more info on the jquery ready function go here: https://api.jquery.com/ready/
see below is my javascript,
<script type="text/javascript">
document.getElementById('auth').onclick=change;
function change(){
this.className="account_holder";
}
</script>
html is
<td id="auth" class="authorised_reportericon" >
<a href="{% url incident.views.authorised_reporter %}">
<p align="center" style="color:black;font-size:16px;">Authorised Reporters</p></a>
</td>
I assigned td's id for onclick,but it is trowing error as Uncaught TypeError: Cannot set property 'onclick' of null
Put document.getElementById('auth').onclick=change; inside of window.onload, like:
window.onload = function () {
document.getElementById('auth').onclick=change;
};
According to the error you're getting, I'm guessing your Javascript is executed before your relevant HTML is rendered, meaning the element with the id "auth" isn't found. Putting it in an event where the whole DOM is ready should fix the problem.
Demo: Here
Most likely you've placed the script in the head of the document, which means it's running before the rest of the page has been rendered.
Instead, move it inside the body, to the very bottom, just before the closing </body> tag.
<!doctype html>
<html>
<head>
<title>my page</title>
</head>
<body>
<!-- your page content -->
<!-- your script -->
<script type="text/javascript">
document.getElementById('auth').onclick=change;
function change(){
this.className="account_holder";
}
</script>
</body>
</html>
Now the elements will be available before the script runs. This is because the page renders in order from top to bottom, and scripts block the rendering when loading.
So when the script is in the head, it prevents the rest of the page below it from rendering until the script is complete, which means the "auth" doesn't yet exist.
Using this positioning technique of the script toward the end allows it to run potentially much sooner than waiting for a window.onload event.
How do I add text/elements to a target element (div) using getElementById (without jquery) when the page loads?
Here's my markup currently:
<html>
<head>
<title>test</title>
<script language="javascript">
/document.getElementById('content').innerHTML = 'Fred Flinstone';
</script>
</head>
<body>
<div id="content">
dssdfs
</div>
</body>
</html>
<script type="text/javascript">
function dothis()
{
document.getElementByID('content').innerHTML = 'Fred Flinstone';
}
</script>
<body onLoad="dothis()">
...
</body>
I think what is happening is that your script is executing before your document is ready. Try placing your javascript in a body load event.
The quickest (although not the best) way to do it is to put your script block towards the end of the HTML file (after the <div> you wish to modify).
The better way to do it is to register for DOM load notification
If you want it to execute after the page loads, then you need to observe the DOM loaded event. You can do that by subscribing to the DOM load event in the script block and then put the code that manipulates the DIV in the event handler.
The tricky part is that different browsers may need slightly different ways to register to be notified when the DOM is loaded (that's were jQuery or a different library becomes useful)
Here's some more information about different ways to register for a callback to be called when the DOM is loaded. The information may be a bit out of date as more modern versions of the popular browsers have become more standards compliant now: http://www.javascriptkit.com/dhtmltutors/domready.shtml
I read that you should define your JavaScript functions in the <head> tag, but how does the location of the <script> (whether in the <head>, <body>, or any other tag) affect a JavaScript function.
Specifically, how does it affect the scope of the function and where you can call it from?
Telling people to add <SCRIPT> only in the head sounds like a reasonable thing to do, but as others have said there are many reasons why this isn't recommended or even practical - mainly speed and the way that HTML pages are generated dynamically.
This is what the HTML 4 spec says :
The SCRIPT element places a script
within a document. This element may
appear any number of times in the HEAD
or BODY of an HTML document.
And some sample HTML. Doesn't it look pretty all formatted here :)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...some JavaScript...
</SCRIPT>
</BODY>
</HTML>
And something to look forward to in HTML 5 :
New async attribute in <SCRIPT> :
Note: There are ways [sic] a script can be
executed:
The async attribute is "true": The
script will be executed asynchrously
with the rest of the page, so the
script will be executed while the page
continues the parsing.
The async attribute is "false", but
the defer attribute is "true": The
script will be executed when the page
is finished with the parsing.
The normal rules of play still stand; don't use stuff before it's defined. :)
Also, take note that the 'put everything at the bottom' advice isn't the only rule in the book - in some cases it may not be feasible and in other cases it may make more sense to put the script elsewhere.
The main reason for putting a script at the bottom of a document is for performance, scripts, unlike other HTTP requests, do not load in parallel, meaning they'll slow down the loading of the rest of your page. Another reason for putting scripts at the bottom is so you don't have to use any 'DOM ready' functions. Since the script tag is below all elements the DOM will be ready for manipulation!
EDIT: Read this: http://developer.yahoo.com/performance/rules.html#js_bottom
One of the aspects of placement is performance. See this fine article within the YSlow discussion for why it's sometimes recommended you put them at the bottom of the document.
As for issues of scope, the usual visibility rules for Javascript (vars defined inside or outside of functions, local, global, closures, etc.) are not affected so far as I know.
Position of script tag does matter.
If you bind a Function with document Element then the document element has to be loaded first before we implement function. suppose getTeachers() is function in getTeachers.js file.
This will give you an error:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<span id="results" /></span>
</body>
</html>
It gives error before head is loaded first and it cannot find element with id specified.
The below code is correction:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
<span id="results" /></span>
</body>
</html>
If your script refers to an ID on the page and the page has not been rendered (i.e. script is before HTML, or your script is executed with onload, rather then the DOM is ready) you can also get an error.
It doesn't. Most programming framework scatter scripts all throughout the page. I've only rarely seen problems because of that (and only from older browsers).
If you pull Javascripts in through XMLHttpRequest, like Diodeus said, it probably won't work. In my case, there was no error, the browser just ignores the new script(s).
I ended up using this, not terribly elegant but works for me so far:
http://zeta-puppis.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/
How to use execJS: http://zeta-puppis.com/2006/02/23/javascript-script-execution-in-innerhtml/
Note: Watch out for < in this line: for(var i=0;i<st.length; i++)
If you have an inline script (outside functions) located before functions it may call, you may get an error because they may not be not available yet. Not saying it is always going to happen, just that it may depending on browser type or version.
Javascript's scoping rules are similar to perl - you can call any function at the current or any higher scope level. The only restriction is that the function has to be defined at the time you call it. The position in the source is irrelevant - only the position in time matters.
You should avoid putting scripts in the <head> if possible as it slows down page display (see the link Alan posted).