getElementById().appendChild()无法工作!

3
我正在尝试从last.fm API中附加一些JSON数据,我已经使用alert()在几个阶段验证了API是否被正确解析,结果是它被正确解析了。这让我得出结论getElementById().appendChild()不起作用,在下面的URL中是我设置的测试页面:http://mutant-tractor.com/tabtest.html。以下是代码:
 
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) {}
}

唯一的方法是使用document.body.appendChild()。
我在head中调用脚本是否有所不同?
我要附加它们的div是4个不同的div,即在for循环中每个循环需要引用不同的元素,
提前致谢! 迈尔斯

1
我在这里的代码中没有看到getElementById,但我绝对相信它有效。 - annakata
你在测试页面上如何重现这个错误? - Ruan Mendes
在代码中生成DOM元素很容易出错。你可能需要研究一下模板引擎。http://api.jquery.com/category/plugins/templates/ 或者 http://code.google.com/closure/templates/docs/helloworld_js.html - Ruan Mendes
3个回答

5

如果在标签中调用脚本,会有什么不同吗?

如果文档主体没有被解析,你将无法使用getElementById()。换句话说,你需要在window.onload函数中运行你的代码,或者将其放在的末尾。

同时,在测试时删除try/catch,这只会隐藏错误。


1
生产环境中完全没有使用try catch的理由。 - Ruan Mendes
1
@Juan - 有合法的使用情况;也许不在提供的代码中,但确实存在真正的用途。让我们不要毫无理由地教条主义。 - ken
1
我的意思是,我不明白相关代码的原因,但并不是完全不理解。我想我的评论表达得不够清楚。 - Ruan Mendes
啊,好的,那很有道理。我会尝试将它放在body的末尾,如果可以的话,我会尝试使用window.onload来外部调用它。 - Myles Gray
@ken - 我会选择一个库,但我只有非常有限的纯Java经验,所以我认为最好的选择是使用纯JavaScript。将其从普通的JS转换为JQuery需要什么? - Myles Gray
显示剩余4条评论

1
你确定你要获取的元素已经被加载到DOM中了吗?你说你的脚本运行在head标签中(在body的其余部分加载之前)。有可能你的脚本在你搜索的DOM元素存在之前就被运行了,因此它找不到它,也就无法添加到它。

0

不能保证 HTML 在 JavaScript 执行时已经完成解析。有几种方法可以实现你想要的效果,具有不同的性能特征。

你可以将代码放在一个函数中,并将其分配为窗口对象的加载事件处理程序。这样做的缺点是需要等待页面的所有资源都加载完成,而不仅仅是 HTML。这通常会减慢页面加载时间,因为你需要等待诸如缓慢的广告服务器等东西。

你可以将代码放在一个函数中,并从文档底部调用它。

你可以使用像 jQuery 这样的 JavaScript 库,在 DOM 完成加载后执行你的 JavaScript。没有一种简单的跨浏览器实现这个的方法,所以最简单的方法就是不要重复造轮子,直接使用已经成熟的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接