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>
Related
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;
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...???
I have a function to grab a video title from a YouTube json callback, which works - however I'm having issues inserting the variable into an element.
Here is the feed I'm grabbing:
<script type="text/javascript" src="http://gdata.youtube.com/feeds/api/videos/2WNrx2jq184?v=2&alt=json-in-script&callback=youtubeFeedCallback"></script>
The javascript function I'm using:
function youtubeFeedCallback(data) {
var info = data.entry.title.$t;
document.write(info);
}
This works fine, but I'd like to insert it into a div with the ID "box".
Usually I would use the following (and add it to the function - and remove the document.write):
var box = document.getElementById('box');
box.innerHTML = info;
I just cannot get this to work though. What would be the correct way to achieve what I'm trying to do? Thanks
http://jsfiddle.net/b3VYT/
Either make sure that the script is below the element or wrap your code in a document.ready callback so that it is not run until after the DOM is loaded.
http://jsfiddle.net/b3VYT/1
You need to make sure that the element that you are using is declared prior to your script executing:
<div id='test'></div>
<script>
function youtubeFeedCallback(data) {
document.getElementById('test').innerHTML = data.entry.title.$t;
}
</script>
Example
I'm just starting to learn javascript, so this is likely a pretty simple question. I've tried searching for an answer, but I think I just don't know enough to be like, 'oh, this looks different but answers my question too.'
What I want to be able to do is to change the background color of a page based on the time of day, and also change an image based on the time of day. I have it working with an if...else if... statement for the background color placed in the head of the page, and a separate if...else if... statement affecting the image in the body.
The head script that changes the bg color looks like:
var d=new Date();
var time=d.getHours();
if (time>=0 && time<=5)
{
document.write ('<body style="background-color: 296688">')
}
else if
...and then the other times follow, each with a different color.
The body script that changes the image looks like:
<img src="" name="sunMoon" id="sunMoon" />
<script type="text/javascript">
var d=new Date();
var time=d.getHours();
var elem = document.getElementById('sunMoon')
if (time>=0 && time<=5)
{
elem.src = 'Images/sunMoon1.png'
}
else if
...and then the other times follow, each with a different src.
Is it possible to change the image AND the bg color using the same if...else if... statement in the head? I tried something like this in the head:
var d=new Date();
var time=d.getHours();
var elem=document.getElementById('sunMoon')
if (time>=0 && time<=5)
{
document.write ('<body style="background-color: 2966B8">');
elem.src="images/sunMoon1.png"
}
else if...
but it didn't work.
I think with the third (nonworking) example, either it's not possible to have a single if... do two things (change the bg color AND the image), or I'm just messing up the image code.
The problem with your third (non-working) bit of code is that you are trying to change the source attribute of an element that doesn't exist when the script is run. Generally speaking the browser parses the page's HTML from top to bottom, when it comes across a block it runs the code then continues on through the HTML. So in the example you have working the JavaScript code that alters the image source comes after the element in the HTML which is why it works. In the broken code you call elem=document.getElementById('sunMoon') in the head section, so no element with ID 'sunMoon' exists yet.
Generally it is best practice to place your scripts at the bottom of the page (just before the closing tag) so that they run after everything else has loaded, and don't block the rendering of the page. If you were to do that you'd need to change the code that alters the background colour as you can't write it directly to the body tag. The best practice solution would be to apply a different CSS class to the body depending on the time of day and then set up style rules for each class in your CSS.
So for example:
<script type="text/javascript">
var body = document.getElementsByTagName('body')[0];
var elem = document.getElementById('sunMoon');
if (time>=0 && time<5)
{
body.className = 'morning';
elem.src = 'Images/sunMoon1.png';
}
else if (time>=5 && time<10)
{
body.className = 'afternoon';
elem.src = 'Images/sunMoon2.png';
}
</script>
Then in your CSS you need rules for .morning, .afternoon etc
Yes you can, you can change the body style like this:
document.body.style.backgroundcolor = color;
Yes you can use
var d=new Date();
var time=d.getHours();
var elem=document.getElementById('sunMoon')
if (time>=0 && time<=5)
{
document.body.style.backgroundImage ="images/sunMoon1.png";
document.body.style.backgroundColor = "#2966B8";
}
use onload event
<html>
<head>
<script>
function onBodyload(e){
var image = document.getElementById('sunMoon');
if(condition){
document.body.style.backgroundcolor = ...
image.src = ...
}else if(condition){
document.body.style.backgroundcolor = ...
image.src = ...
}else if...
}
</script>
</head>
<body onload="onBodyload">
...
...
</body>
</html>