This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does jQuery or a DOM method such as `getElementById` not find the element?
I've been trying to learn js, but im having trouble getting a very simple example to work and i cant seem to find what im doing wrong. From all i understand the below example should work. When i click on the second button, it calls the function f2 and outputs "batman" as an alert, so i know the javascript page is linked correctly. But when i click on the first button nothing happens.
HTML:
<head>
<script type="text/javascript" src="Positioning and flow tests.js"></script>
</head>
<body>
<p id="par1">Test</p>
<button onclick="f1()">Click me for par 1 content</button>
<button onclick="f2()">Click me for predefined text</button>
</body>
</html>
Javascript
// JavaScript Document
var var1 = document.getElementById("par1");
function f1()
{
alert(var1.innerHTML);
}
function f2()
{
alert("batman");
}
You have to put the JavaScript at the bottom of the page, otherwise the par1 element won't be available when your code runs:
<head>
<title>Positioning and flow tests</title>
</head>
<body>
<p id="par1">Test</p>
<button onclick="f1()">Click me for par 1 content</button>
<button onclick="f2()">Click me for predefined text</button>
<script type="text/javascript" src="Positioning and flow tests.js"></script>
</body>
An alternative to this, is to set your code to run when the page has finished loading:
var var1;
window.onload = function () {
var1 = document.getElementById("par1");
};
function f1()
{
alert(var1.innerHTML);
}
function f2()
{
alert("batman");
}
but this will wait until the page has completely loaded, which includes downloading all the images. If you were to click on the first button before all the images have been fully downloaded, you'd get an error.
You need to either put the code after the element or do this:
HTML:
<body onload="init()">
...
JS:
var var1;
function init() {
var1 = document.getElementById("par1");
}
function f1()
{
alert(var1.innerHTML);
}
The problem is you are trying to get an element that has yet to be created and therefore doesn't exist. Using an 'init' function will wait until the entire document has loaded before trying to get the elements.
Related
Below is an example of a problem I am having. I am using $(locator).html(data) to replace a DIV after an ajax call. The issue is that the DIV also have a SCRIPT tag inside it, and those functions in that SCRIPT tag are remaining in memory after I .empty() that DIV.
Is there a way to remove/de-register/undefine all functions in the SCRIPT tag automatically/programmatically? I guess I thought the Jquery .empty() would do that, but I guess not. I think I could do something manual like test1 = undefined but I don't want to have to explicitly do that for all the functions.
Thanks.
EDIT: I am working on a legacy product, so there are dozens of html files with dozens of functions that could be loaded for the newString variable. So my goal is not to change any of those, but to solve this lingering-function issue at the time of .empty() and .html() when replacing the div contents.
EDIT 2: And I can't just "delete" the function, because I don't always know what the function(s) will be. I need to do this programmatically. (seems I keep getting flagged as a duplicate question, but again, I can't delete what I don't know yet)
function change () {
// this newString is mock html data coming back from an ajax call
let newString = "<p>Reloaded page</p>";
console.log("#emptyme HTML before empty():")
console.log($("#emptyme").html());
$("#emptyme").empty();
console.log("#emptyme HTML AFTER empty():")
console.log($("#emptyme").html());
$("#emptyme").html(newString);
if (typeof test1 !== "undefined") {
$("#error").html("test1() WAS STILL FOUND!!");
console.log("test1() WAS STILL FOUND!! Function definition from memory is:");
console.log(test1);
}
console.log("finished change function.");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="emptyme">
<p>
Initial page
</p>
<script>
function test1 () {
console.log("this is test1 function.");
}
</script>
</div>
<button onclick="change()">
load change
</button>
<div id="error">
</div>
</body>
</html>
JavaScrip has an internal garbage collection and your code does not have to destroy things like you would do in C++
However, at Certain times we would want to "destroy a function" where it is resources expensive
Because js runs from top to bottom you can overwrite that function if you have called it in a variable later in the program to free up those resources. Or even do it later in the logic of the program
var ExpensiveFunction =( function () {
//..code
function getRidOfthis1(){ console.log("foo1"); }
function getRidOfthis2(){ console.log("foo2"); }
function getRidOfthis3(){ console.log("foo3"); }
function getRidOfthis4(){ console.log("foo4"); }
//initiate an internal reference to them
ExpensiveFunction.getRidOfthis1 = getRidOfthis1;
ExpensiveFunction.getRidOfthis2 = getRidOfthis2;
ExpensiveFunction.getRidOfthis3 = getRidOfthis3;
ExpensiveFunction.getRidOfthis4 = getRidOfthis4;
} );
//Functions available outside of the nesting
ExpensiveFunction()
ExpensiveFunction.getRidOfthis1();
ExpensiveFunction.getRidOfthis2();
// overidding it
ExpensiveFunction =0
What im trying to do, is to call my function from whenever someone clicks on my button. However, i know that it can be done with
<button onclick="myFuntion()>
But i want to skip that step, i dont want a function in my button, i've heard that its bad programming.
However, heres how my file looks.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javacript" src="javascript.js"> </script>
<title> Javascript </title>
<script>
function testFunction(){
document.getElementById("test").onclick = Hello;
}
function Hello(){
alert("Hello");
}
</script>
</head>
<body>
<button type="button" id="test" <!-- I know i can use onclick="testFunction()" here but i dont wanna !-->> Click me </button>
</body>
</html>
So how come it doesnt pop-up with the box "Hello" whenever i push the button, what have I done wrong?
You have to call your testFunction after the HTML body is loaded so that it actually creates he binding.
That is, at the end of the file, you'd do something like:
...
<script>
testFunction()
</script>
</body>
...
If you run that binding code in your head script the button element won't exist yet — that is why this have to be at the end.
JavaScript libraries such as jQuery make this more elegant by providing an ready hook, where one puts code to be called once the page is fully loaded, without having to resort to code on the bottom of the page.
Complete example with script at end (confusingly, Stack Snippets don't show it to you in the order they actually are in the snippet; even though it doesn't look like it, the script is at the end here):
// Scoping function to avoid creating unnecessary globals
(function() {
// The click handler
function Hello() {
alert("Hello");
}
// Hooking it up -- you *can* do it like you did:
//document.getElementById("test").onclick = Hello;
// ...but the modern way is to use addEventListener,
// which allows for more than one handler:
document.getElementById("test").addEventListener(
"click", Hello, false
);
})();
<button type="button" id="test">Click me</button>
window.onload=testFunction;
function testFunction(){
document.getElementById("test").onclick = Hello;
}
function Hello(){
alert("Hello");
}
Just run the line in your testFunction always. As seen here:
https://jsfiddle.net/arugco4b/
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/
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 7 years ago.
Rookie alert!
Would you tell me why my Javascript code doesn't update the message. The browser runs HTML but ignores the Javascript code. What am I doing wrong?
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site! </div>
</body>
</html>
You're running the Javascript before you've loaded the body, the message element doesn't exist yet. Either move the script to the end of the <body>, or change the last line to:
window.onload = updateMessage;
so that the function will be loaded after the HTML is loaded.
If the <script> tag is in the <head> element, it gets executed before the HTML elements in the <body> are created. You can put your script tag inside the <body> element, at the end of it, to solve the issue.
Assuming you don't simply have javascript disabled, you could add a window.onload=function(){ surrounding your code.
window.onload=function(){
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
}
The reason for doing this is because your javascript code is inside your <head>. Thus, the javascript is loaded before the body. When the browser attempts to execute the javascript code, the message element isn't loaded yet and doesn't exist. By adding window.onload=function(){ to surround your code, your entire code will wait until the body is loaded before executing.
When you call your javascript code, the 'message' element isn't already there. I would suggest one of the following two things:
+Put your javascript code at the end of the body ( note that it only need to be after 'message', but putting it at the end is generally the best option )
+Replace your call with window.onload = updateMessage, which will wait until all the page is loaded to execute your javascript
There are already lots of duplicate answers here but there is another way, especially if you want to keep your Javascript code in a script tag in the head. And that is, wrap your Javascript function call in setTimeout -- this causes the function to be executed after the DOM has been parsed, but before the entire window has been loaded.
It's a neat little trick that can be used when you don't have a framework's (such as jQuery) document/ready functionality. window.onload or putting the script at the bottom might cause significant delays if there is lots of heavyweight content (large images?) in the page.
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
setTimeout(updateMessage);
</script>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site!</div>
<img src="http://cdn.spacetelescope.org/archives/images/publicationjpg/heic1502a.jpg" />
</body>
</html>
Notice I have added a very large image to the page, but the updated message displays before the image fully loads.
If however instead of setTimeout(updateMessage); you use window.onload = updateMessage; as suggested in the currently accepted answer, your message will not get updated until the entire image loads (if you try this out, make sure you do a hard refresh after the first time so you are not getting it from your cache). Same goes for moving the script too far down the page (below the very large image for instance) as below. I honestly think, if you don't have a framework's document/ready functionality, using setTimeout in a script block in the head is the best solution.
MESSAGE NOT UPDATED UNTIL AFTER IMAGE LOADS:
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site!</div>
<img src="http://cdn.spacetelescope.org/archives/images/publicationjpg/heic1502a.jpg" />
</body>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</html>
You are trying to make the changes before the DOM is loaded. See the code below,
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site! </div>
</body>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</html>
I'm developing a dynamic web page with nested pages. Inner pages have their own script to be live and modular.
The problem comes when i want to remove one of the inner pages. Infact the HTML code is removed but the inner script keeps running.
Is it possible to stop the script?
This is a brief view of my solution:
Note that in this sample the ID are all the same but in the real solution they are identified by unique ID using php GET["ID"] value.
outerPage.php
<HEAD>
<script>
var fRunUpdate = true;
$(document).ready(function() {
$("#inner1").load("inner.php");
$("#inner2").load("inner.php");
$("#inner3").load("inner.php");
}
</script>
</HEAD>
<BODY>
<div id="inner1"></div>
<div id="inner2"></div>
<div id="inner3"></div>
</BODY>
innerPage.php
<HEAD>
<script>
var fRunUpdate = true;
$(document).ready(function() {
function update(){
//do something
$("#contentToUpdate").html("content");
setTimeout(update,1000);
}
}
</script>
</HEAD>
<BODY>
<div id="contentToUpdate"></div>
</BODY>
You will have to use stoptimeout or clear interval
I just read out this link and get it
How to stop a setTimeout loop?
Take function in variable
foo = setTimeout(function, time);
and then just clear it out
clearTimeout(foo);
I hope this will help you