I have this function which is trying to change the src property of an img. Here's the Javascript:
function transition(){
document.getElementById("firstfirst").src = marray[currArrayValue];
currArrayValue++;
if(currArrayValue == array.length-1){
currArrayValue = 0;
}
setTimeout(transition(), 1000);
}
My google chrome console is saying document.getElementById("firstfirst") doesn't exist, but it definitely does. Here's the HTML:
<div id="banners-container">
<div id="banners">
<img src="images/banners/top-banner-one.png" id="firstfirst" alt="Subscribe now to get access to thousands of vintage movies!" border="0">
</div>
</div>
What gives?
Javascript is executed as soon as it has been parsed.
If your JS is included in the <head> of your webpage, it will be executed before the document body has been parsed and the DOM has been built.
As such, you need to engineer your code so that it is not executed until the DOM has been loaded. You might want to look at the MDN docs on the DomContentLoaded event. Alternatively, you can use one of the many JavaScript libraries out there which wrap this up for you.
if chrome says the element is null it is null. Perhaps you are calling function before the element loaded in DOM. like calling the function in head tag prior the element tag.
so try something like this.
<html>
<head>
<script>
function F () { /*reach element*/ }
</script>
</head>
<body>
//The element
</body>
<script>
F ();
</script>
</html>
Related
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/
I have the follwing JavaScript.
<html>
<head>
<script language="JavaScript">
function fdivisible()
{
document.write("<h1> Just a javascript demo</h1>");
var x=document.forms["aaa"]["txt1"].value;
alert(x);
}
</script>
</head>
<body>
<form action="#" name="aaa">
Enter a no. : <input type="text" name="txt1" id="txt1" />
<input type="button" value="Click" onclick="fdivisible();">
</form>
</body>
</html>
The problem is, the first line of the JS function is executing and the rest are ignored. If I comment out the first line the rest of the code is executed. Can anybody explain to me why it is so?
Because calling document.write implicity calls document.open, which clears the document on which it has been called:
If a document exists in the target, this method clears it
After the call to document.write, the element you're trying to get a reference to no longer exists in the DOM, and an error is thrown. If you look in the error console it should be something along the lines of the following:
TypeError: Cannot read property 'txt1' of undefined
document.write can only be used during the initial loading of the document.
If you want to insert your H1 when the function is called, you may replace
document.write("<h1> Just a javascript demo</h1>");
with
var h1 = document.createElement('h1');
h1.innerHTML = " Just a javascript demo";
document.body.appendChild(h1);
document.write(content) writes content on the document stream.
You have to close the stream after writing on the document in order to continue the page loading
document.write("hello");
document.close();
https://developer.mozilla.org/en-US/docs/DOM/document.write
https://developer.mozilla.org/en-US/docs/DOM/document.close
https://developer.mozilla.org/en-US/docs/DOM/document.open
With addition to dystroy answer, you could replace document.write with:
document.body.innerHTML += '<h1>Javascript demo</h1>
You're destroying the DOM with your document.write call. In some browsers, this also destroys global variables.
Instead use:
var element = document.createElement('h1');
element.appendChild(document.createTextNode('text'));
document.body.appendChild(element);
use document.write() at the end of all JS statements. The script element is never executed after it.
Try this:
var x=document.getElementById(txt1).value;
alert(x);
You can write to the document with
document.write("<h1> Just a javascript demo</h1>");
only once and it applies to the whole document. If you want to put you will have to add a class/id to it and then put text in that class/id.
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.
I have a JS script which created a new Node and inserts it to the HTML page. I am handling DOM mutation events and can capture DOMNodeInserted event. Inside that function I want to find out the source (i.e. in which part of the HTML has the script function been called) and the target (i.e. in which part the node is being added in the HTML page).
I am able to find the target using event.target, but I am not able to find the source of the event.
For example, consider the following pseudocode HTML page:
<html>
<head>
<script>
function test() {
//DOM access
<div_object>.setAttribute("attr", "value");
}
</script>
</head>
<body onload="test()">
<div id="123">
</div>
</body>
</html>
I want my source to be BODY (because that is were the script is initiated), target should be div(123) (because the attribute is added to div_123.
How can I do this?
Sorry, you can't find out what piece of code caused an event to be triggered, they're completely decoupled. You would have to have the triggering code co-operate by storing the values of its own this/event.target in a variable for the triggered code to pick up later.
But then if you have co-operation like that, you wouldn't need DOM Mutation Events.
If you have an event handling layer (as is part of many JS frameworks), you could put the this/target tracking in that layer, so the triggered code could ask “what was the last event that fired, before me?”.
But I'm not convinced this would be worth it. It's usually best to add your own co-operative hooks that communicate between components; you can't generally rely on DOM Mutation Events since they're not globally and completely supported (or indeed supported at all on IE<9).
What about
<html>
<head>
<script>
function test(element) {
//DOM access
element.setAttribute("attr", "value");
}
</script>
</head>
<body onload="test(this)">
<div id="123">
</div>
</body>
</html>
?
Interesting. I had a look here (answered to get formatting)
<html>
<head>
<script>
function test(e) {
if (e) var event=e;
//DOM access
var t="";
for (o in event) t+='<br/>'+o+':'+event[o]
document.getElementById('d123').innerHTML=t;
}
</script>
</head>
<body onload="test(event)">
<div id="d123">
</div>
</body>
</html>
I'm trying to write a javascript function that adds some DOM nodes to the document in the place it was called, like this:
...
<div>
<script type="text/javascript">
pushStuffToDOMHere(args);
</script>
</div>
...
i try to do it 'cleanly', without using node id property of the div, or innerHTML string manipulation. for that I need to know where in the document the script tag is located.
is there a way to do it?
Talking about cleanly, I don't think your approach is particularly clean. It is a much better idea to give the div a unique id and execute your javascript when the DocumentReady-event fires.
Do you have an overriding reason for doing it this way? If not the suggestion to use a unique id makes the most sense. And you can always use a library like jQuery to make this even easier for yourself.
However, the following quick test shows that if you use document.write() in the function then it writes the value into the place where the function was called from.
<html>
<head>
<script type="text/javascript">
function dosomething(arg){
document.write(arg);
}
</script>
</head>
<body>
<div>The first Div</div>
<div>The
<script type="text/javascript">
dosomething("Second");
</script>
Div
</div>
<div>The
<script type="text/javascript">
dosomething("Third");
</script>
Div
</div>
</body>
</html>
But, again the question, are you sure this is what you want to do?
Although I agree with n3rd and voted him up, I understand what you are saying that you have a specific challenge where you cannot add an id to the html divisions, unless by script.
So this would be my suggestion for inlining a script aware of its place in the DOM hierarchy, in that case:
Add an id to your script tag. (Yes, script tags can have ids, too.)
ex. <script id="specialagent" type="text/javascript">
Add one line to your inline script function that gets the script element by id.
ex. this.script = document.getElementById('specialagent');
...And another that gets the script element's parentNode.
ex. var targetEl = this.script.parentNode;
Consider restructuring your function to a self-executioning function, if you can.
Ideally it executes immediately, without the necessity for an 'onload' call.
see summary example, next.
SUMMARY EXAMPLE:
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode.nodeName=="DIV" && this.script.parentNode;
//...your node manipulation here...
}('arg1','arg2','arg3');
</script>
The following TEST code, when run, proves that the function has identified its place in the DOM, and, importantly, its parentNode. The test has division nodes with an id, only for the purpose of the test. They are not necessary for the function to identify them, other than for testing.
TEST CODE:
<html>
<head>
<title>Test In place node creation with JS</title>
</head>
<body>
<div id="one">
<h2>Child of one</h2>
<div id="two">
<h2>Child of two</h2>
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode;
/*BEGIN TEST*/
alert('this.script.id: ' + this.script.id);
alert('targetEl.nodeName: ' + targetEl.nodeName + '\ntargetEl.id: '+targetEl.id);
alert('targetEl.childNodes.length: ' + targetEl.childNodes.length);
var i = 0;
while (i < targetEl.childNodes.length) {
alert('targetEl.childNodes.'+i+'.nodeName = ' + targetEl.childNodes[i].nodeName);
++i;
}
/*END TEST - delete when done*/
//...rest of your code here...to manipulate nodes
}('arg1','arg2','etc');
</script>
</div>
</div>
</body>
</html>
Not really sure what your trying to achieve but this would pass the dom element to the function when clicked. You could then use jquery in the function to do what you wanted like so
...
<script type="text/javascript">
function pushStuffToDOMHere(element)
{
$(element).append("<p>Hello</p>"); // or whatever
}
</script>
<div onclick="pushStuffToDOMHere(this);">
</div>
...
my solution is a compbination of the (good) answers posted here:
as the function is called, it will document.write a div with a unique id.
then on document.onload that div's parent node can be easily located and appended new children.
I chose this approach because some unique restrictions: I'm not allowed to touch the HTML code other than adding script elements. really, ask my boss...
another approach that later came to mind:
function whereMI(node){
return (node.nodeName=='SCRIPT')? node : whereMI(node.lastChild);
}
var scriptNode = whereMI(document);
although, this should fail when things like fireBug append themselves as the last element in the HTML node before document is done loading.