This is a piece of code that links to a javascript file that generates some fake tweets, along with some self made comments that attempt to explain to myself what is happening. I was wondering what the purpose of $body.html(''); was. It seems like it just clears the contents of the body, which is already empty except for the javascript that is present. Wouldn't this also clear the actual script that inside the body as well? i.e., why doesn't the whole script just vanish when we reach that line. I'm guessing that the function is executed in its entirety before the body is cleared? Just looking for a little illumination, I guess, on function execution.
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script src="data_generator.js"></script>
</head>
<body>
<script>
$(document).ready(function(){ // calls function only after dom is loaded
var $body = $('body'); // selects html body tag, stores in $body
$body.html(''); // clears body?
var index = streams.home.length - 1; // sets index to length of streams array
while(index >= 0){
var tweet = streams.home[index]; // gets a tweet string
var $tweet = $('<div></div>'); // $tweet is a div element
$tweet.text('#' + tweet.user + ': ' + tweet.message); // add formatted tweet to div
$tweet.appendTo($body); // add tweet to body
index -= 1; // rinse, repeat
}
});
</script>
</body>
</html>
EDIT: To be clear, I didn't write the code, only the comments. I am just trying to break it down and understand each line.
When the Javascript is run the function context is stored in memory, and closed-over variables are stored in the context. They don't go away. Globals are attached to window. They don't go away either.
I think it is a better idea to append the script to the header (where all the other scripts reside) than to the body.
If you want to completely eliminate the script that is being called, you could use:
<script>
(function foo(){
var b=function moo(){
var c=document.getElementsByTagName('script');
alert(document.body.innerHTML);
c[0].parentElement.removeChild(c[0]);
alert(document.body.innerHTML);
}
var a=setTimeout(b,1000);
b=null;
})();
foo=null;
</script>
Keep in mind, that will COMPLETELY remove any functionality of the script and any reference to it in the DOM.
Basically, because the script has already loaded, you can't just remove it from the DOM.
Is there really any reason to get rid of it, now that it's already loaded...???
Related
from an issue I am experiencing I understand how it works, but I can't find any formal reference that helps me to clarify the behaviour.
<head>
<title>Chapter 7: Example 7</title>
<script type="text/javascript">
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
</script>
</head>
<body>
<form action="" name="form1">
<select name="theDay" size="5">
<option value="0" selected="selected"></option>
With this code I receive an error on line "weekDays = formWeek.theDay.options;" because "theDay" is not defined. So I believe that while the JS code is executed the browser has not parsed and loaded the DOM (hence it doesn't know about form1).
If I move the variable definition inside the function, everything works fine.
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
}
At function execution the browser knows about form1 (load all the HTML code).
So... from the code the behaviour is clear but still it has not 'clicked' on my mind how it works.
I thought that the link below was a good reference to understand the behaviour.
Where should I put <script> tags in HTML markup?
Can you point me to some good reading that explains HTML-JS loading?
For what i know, javascript is loaded in line with HTML. So if you have an element <foo> and then a script that uses <foo> after that, it works. Turn them around, and the script is loaded first, after that the foo element. This way your script cannot find the element.
Change your javascript to:
function init()
{
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
}
document.addEventListener('DOMContentLoaded', init, false);
this way you make sure the javascript is loaded when the DOM is ready.
When you have an inline script tag in HTML, it blocks the parsing of HTML and it is executed immediately. Anything written after it has not been parsed yet.
It's common practice to put script tags at the end of the body tag, because at that point the DOM has been parsed and JS can safely execute.
As far as the error you pointed out is concerned, you can wait for the browser to finish loading the page by using something like window.onload. Notice lower in the documentation, in the Notes section
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.
This means by the time the code is run, your HTML has been parsed and put into the DOM. Your script tag, then, will be:
<script type="text/javascript">
window.onload = function() {
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
}
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
</script>
I have a js function that takes an html node and fades it from yellow to white. But it only works if before calling it from my js file I add text to body element via document document.writeln('Hi');. If I write text directly in my html file and don't call document.writeln then I don't see the fade effect after opening index.html.
<!DOCTYPE html>
<html>
<head>
<script src="program.js"></script>
</head>
<body style='width: 100%; height: 100%'>
Hi
</body>
</html>
JS file:
'use strict';
document.writeln('Hi'); // If we comment out this line we don't see the fade effect.
// Define a function that sets a DOM node's color
// to yellow and then fades it to white.
var fade = function (node) {
var color = 1;
var step = function () {
var hex = color.toString(16);
node.style.backgroundColor = '#FFFF' + hex + hex;
if(color < 15) {
color++;
setTimeout(step, 100);
}
}
setTimeout(step, 100);
};
fade(document.body);
EDIT:
Using window.onload for fade function also does not help.
I tried to use this one and it works without any errors:
document.addEventListener('DOMContentLoaded',function(){
fade(document.body);});
If the DOM is not loaded yet, you can't change it. So, this listener might help.
As described here, if you call Document.writeln() the browser calls Document.open() before, so there is an existing Document object. That might be the reason, why it worked, when you added this line before.
https://developer.mozilla.org/de/docs/Web/API/Document/write
You can also move the <script src="program.js"></script> to right before the </body> tag.
Is the function wrapped in a
$(document).ready(function()
{
//Function goes here
});
or a
window.onload = //function name here
if not, use either one & it should be working
EDIT
I've forgotten to say that you shouldn't forget to add jQuery before the external js file
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
I was trying to check some of javascript code and I found one thing which I am not able to understand the exact reason. In my html file, I have a div with id called test which dont have any value. Now, I want to update the a text/ sentence inside this div through innerHTML. as it is just for testing purpose I am not using any function/ event. Just adding a to update the value.
<body>
<script type="text/javascript">
var test_content = "This is new text in my test div";
document.getElementById("test").innerHTML = test_content;
</script>
<div id="test"></div>
</body>
Now, when I load the page, it showing empty nothing inside the test div but if put the javascript code below the div as in below, then it is showing the value in the variable. (note: I am not using any function nor event, just want to update on page load).
<body>
<div id="test"></div>
<script type="text/javascript">
var test_content = "This is new text in my test div";
document.getElementById("test").innerHTML = test_content;
</script>
</body>
can any one explain me the reason for this? Thanks in advance.
Thanks!
Robin
That's because the first is executed before the div#test is created, so it currently doesn't exist. That's why is a good practice to either put your script tags at the bottom of the page or wrap them with an window.onload event listener.
<body>
<script type="text/javascript">
window.onload = function () {
var test_content = "This is new text in my test div";
document.getElementById("test").innerHTML = test_content;
}
</script>
<div id="test"></div>
</body>
If you are using jQuery, you can also do this:
$(function () {
var test_content = "This is new text in my test div";
document.getElementById("test").innerHTML = test_content;
});
And since you seem to be a beginner in JavaScript coding, I recommend you read some articles on MDN, like this one and this one.
Pretty standard issue. Needs an 'onload' of some sort!
<body>
<div id="test"></div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var test_content = "This is new text in my test div";
document.getElementById("test").innerHTML = test_content;
});
</script>
</body>
The reason this is not happening in the the first instance, is because the DOM element, 'test' has not been created yet.
When you place the script after the div, the element has already been created and hence, the script can execute.
You will need to execute your code once the DOM is ready, by listening for load event dispatched from the body tag. This can be done quite simply using an in-line listener such as <body onload='myFunction'> or by an onload handler in javascript:
body.onload = function() {...}
Javascript is executed at runtime, as soon at it is being called. In your first example, the parser reads the script tag, executes it and then loads the rest of the page (top-to-bottom). As the script is executed before the div is laoded and created, the div will stay empty. That's the reason the onload event was introduced. http://www.w3schools.com/jsref/event_onload.asp
take one example of jquery you either have to write $(document).ready() or you have to write your jquery code at the last of html code and, both have same meaning i.e when all the html is loaded then do some function. this is same in this case, do some function after all the document content is loaded. take two cases:
case #1:
in this case we have the javascript code written above the html as in your first case which is without any event handler, the html engine will start reading the html code from top to bottom and at the moment it will hit to script tag it will call javascript engine. so according to this javascript code will be executed first.
if you write this line document.getElementById("test").innerHTML = test_content;
as :
var x = document.getElementById("test");
x.innerHTML = test_content;
then the console will return null i.e the value of x would benull.because div is still not loaded, therefore the value of div will not change
case #2:
script tag is placed at the last. so now, all the html is loaded by html engines, so now the value of x will be <div id="test"></div> and now all the javascript code will be executed without any error.
as i mentioned earlier about jquery $(document).ready()... well this is a jquery method but this can be written as in javascript as:
<script type="text/javascrip">
var start_script = function(){
// function to be performend
}
</script>
<body onload="start_script();">
......
</body>
because all the event are triggered when all the html is loaded and compiled.
I have been working on a complex project for the past few weeks when I encountered this bizarre bug. I have since isolated my problem in the code below, which is the smallest possible valid HTML and JS that reproduces it:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chat</title>
<script type="text/javascript">
//<![CDATA[
function refresh()
{
var old = document.getElementById("conversation").innerHTML;
var message = '<img/>';
if(old != message) {
alert("Old:\n" + old);
alert("New:\n" + message);
//alert("Refreshed!");
document.getElementById("conversation").innerHTML = message;
}
}
//]]>
</script>
</head>
<body onload="refresh()">
<div id="conversation"></div>
<script type="text/javascript">var myVar = setInterval(function(){refresh();},1000);</script>
</body>
</html>
Every second, the function refresh() checks to see if the code in the div is different than the stored string. If it is different, it replaces the div's contents with the string. However, each time it checks, it sees the contents and the stored string are different. Although the string is <img/>, the innerHTML is returned as <img>. I figured out that for any self-closing tag, it automatically removes the slash. For a tag that isn't supposed to be self-closing (like <i>), it automatically splits it into two tags (like <i></i>). For any other tag or text, it does nothing.
I don't really understand why the div's contents are changing at all. If anyone can explain why, I would appreciated it. If someone can even provide a possible solution, I would be grateful.
That's because the browser is using an HTML parser, not an XML parser for the page, that's why it will remove the closing slash.
I'm a relative novice myself but I think what Matt Ball is referring to is the fact that you are creating a string when you should be creating a new DOM element So one simple change to your function would be:
var convo = document.getElementById("conversation");
function refresh() {
var old = convo.innerHTML;
var message = document.createElement("IMG");
if (old != message) {
alert("Old:\n" + old);
alert("New:\n" + message);
//alert("Refreshed!");
convo.innerHTML = message;
}
}
Here is a FIDDLE
Note: I added the global convo variable to reduce keystrokes and use document.createElemet instead of innerHTML to add the new image element to the DOM. You can then call upon that image element inside or outside your function using the firstChild method like this:
convo.firstChild;
I have multiple script tags in a web page. Will having the same variable name in more than one script tag cause issues with the variables getting the wrong value from an above script tag?
<script type="text/javascript">
var current = 0;
</script>
<script type="text/javascript">
var current = 1;
</script>
Will the first current cause issues with the second occurence?
Yes it will. There is only one global execution context, doesn't matter how many <script> nodes you have in your HTML markup.
So in this particular example, current gets initialzed on the window object with 0 and then gets overwritten with 1.
You won't ever run into a situation where code that's executed immediately after the var current = 1 in your second <script> tag will be using current with a value other than 1. To provide a very basic example:
<script type="text/javascript">
var current = 0;
alert(current); // will always alert 0
</script>
<script type="text/javascript">
var current = 1;
alert(current); // will always alert 1, never 0
</script>
That should answer the "cause issues with the variables getting the wrong value from an above script tag" aspect of the question.