Im trying to append some JSON data from the last.fm API,
I have been using alert() at several stages to verify the API is being parsed correctly and it is,
This has led me to the conclusion that getElementById().appendChild() doesn't work, below is the URL to the test page I have set up:
.html
Code here
function calculateDateAgo(secAgo) {
var agoString, agoRange, agoScaled;
if(secAgo >= (agoRange = 60*60*24))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"days":"day") + " ago"
else if(secAgo >= (agoRange = 60*60))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"hours":"hour") + " ago"
else if(secAgo >= (agoRange = 60))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"minutes":"minute") + " ago"
else if(secAgo >= -60)
agoString = "blastin' out now";
else
agoString = "soon ;)";
return agoString
}
function truncateName(name, l) {
return name.length > l ? name.substr(0,l-2) + "\u2026" : name
}
function lfmRecentTracks(JSONdata) {
try {
var eImg, eLink, eSpan, divTag, eWrapper;
var oTracks = new Array().concat(JSONdata.recenttracks.track);
for (var i = 0; i [lessthanhere] oTracks.length; i++) {
//insert track link
spanTag = document.createElement("span");
spanTag.className = "lfmTrackInfoCell tabslider";
eLink = document.createElement("a");
eLink.appendChild(document.createTextNode( truncateName(oTracks[i].name, 25) ));
//alert(truncateName(oTracks[i].name, 25));
spanTag.appendChild(eLink);
eLink.href = oTracks[i].url;
//alert(oTracks[i].url);
eLink.target = "new";
eLink.className = "lfmTrackTitle";
document.body.appendChild(spanTag);
//insert artist name
eSpan = document.createElement("span");
eSpan.appendChild(document.createTextNode(truncateName(oTracks[i].artist["#text"], 22) ));
//alert(truncateName(oTracks[i].artist["#text"], 22));
eSpan.className = "lfmTrackArtist";
document.body.appendChild(eSpan);
//insert date
eSpan = document.createElement("span");
spanTag.appendChild(eSpan);
eSpan.appendChild(document.createTextNode( (typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts)) ));
//alert((typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts)));
eSpan.className = "lfmTrackDate";
document.body.appendChild(eSpan);
}
} catch(e) {}
}
The only way it works is by using document.body.appendChild()
I'm calling the script in the head if that makes a difference?
The div I'm trying to attach them to are 4 different divs i.e. in the for loop each loop needs to reference a different element,
Thanks in advance! Myles
Im trying to append some JSON data from the last.fm API,
I have been using alert() at several stages to verify the API is being parsed correctly and it is,
This has led me to the conclusion that getElementById().appendChild() doesn't work, below is the URL to the test page I have set up:
http://mutant-tractor./tabtest.html
Code here
function calculateDateAgo(secAgo) {
var agoString, agoRange, agoScaled;
if(secAgo >= (agoRange = 60*60*24))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"days":"day") + " ago"
else if(secAgo >= (agoRange = 60*60))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"hours":"hour") + " ago"
else if(secAgo >= (agoRange = 60))
agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"minutes":"minute") + " ago"
else if(secAgo >= -60)
agoString = "blastin' out now";
else
agoString = "soon ;)";
return agoString
}
function truncateName(name, l) {
return name.length > l ? name.substr(0,l-2) + "\u2026" : name
}
function lfmRecentTracks(JSONdata) {
try {
var eImg, eLink, eSpan, divTag, eWrapper;
var oTracks = new Array().concat(JSONdata.recenttracks.track);
for (var i = 0; i [lessthanhere] oTracks.length; i++) {
//insert track link
spanTag = document.createElement("span");
spanTag.className = "lfmTrackInfoCell tabslider";
eLink = document.createElement("a");
eLink.appendChild(document.createTextNode( truncateName(oTracks[i].name, 25) ));
//alert(truncateName(oTracks[i].name, 25));
spanTag.appendChild(eLink);
eLink.href = oTracks[i].url;
//alert(oTracks[i].url);
eLink.target = "new";
eLink.className = "lfmTrackTitle";
document.body.appendChild(spanTag);
//insert artist name
eSpan = document.createElement("span");
eSpan.appendChild(document.createTextNode(truncateName(oTracks[i].artist["#text"], 22) ));
//alert(truncateName(oTracks[i].artist["#text"], 22));
eSpan.className = "lfmTrackArtist";
document.body.appendChild(eSpan);
//insert date
eSpan = document.createElement("span");
spanTag.appendChild(eSpan);
eSpan.appendChild(document.createTextNode( (typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts)) ));
//alert((typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts)));
eSpan.className = "lfmTrackDate";
document.body.appendChild(eSpan);
}
} catch(e) {}
}
The only way it works is by using document.body.appendChild()
I'm calling the script in the head if that makes a difference?
The div I'm trying to attach them to are 4 different divs i.e. in the for loop each loop needs to reference a different element,
Thanks in advance! Myles
Share Improve this question asked Jan 11, 2011 at 17:11 mylesagraymylesagray 8,8797 gold badges50 silver badges71 bronze badges 3- 1 I don't see getElementById in the code here, but I absolutely believe it works. – annakata Commented Jan 11, 2011 at 17:14
- How do you reproduce the error on your test page? – Ruan Mendes Commented Jan 11, 2011 at 17:15
- Generating DOM elements in straight code is very error prone. You might to to look into templating engines. api.jquery./category/plugins/templates or code.google./closure/templates/docs/helloworld_js.html – Ruan Mendes Commented Jan 11, 2011 at 17:17
3 Answers
Reset to default 4I'm calling the script in the head if that makes a difference?
You won't be able to getElementById()
if the document body hasn't even been parsed. In other words, you need to run your code in an window.onload
function, or place it at the very bottom of your body.
Also, remove the try/catch
while testing, it will only hide errors.
Are you sure that the element you're trying to get has been loaded into the DOM? You said that your script runs in the head tag (which loads before the rest of the body loads). It's possible that your script is being run before the DOM element you're searching for exists, and therefore it can't find it and therefore it can't add to it.
There's no guarantee that the HTML will have finished parsing by the time the JavaScript executes. There are several ways of doing what you want, with different performance characteristics.
You can put your code in a function and assign it as the load event handler for the window object. This has the downside of waiting until all resources for the page have finished loading, not just the HTML. This often slows down page load times, as you need to wait for things like slow ad servers etc.
You can put your code in a function and call it from bottom of the document.
You can use a JavaScript library such as jQuery to execute your JavaScript when the DOM has finished loading. There isn't a simple way of doing this that works cross-browser, so it's simplest not to reinvent the wheel and just to use what is already a mature solution.