立即在Javascript中更新DOM元素
问题描述:
对于一个简单的项目,我试图在textarea中显示日志输出。我有一个log
函数,并且希望textarea在调用log
时总是立即更新。不幸的是,它似乎只执行一次更新,并且同时推送所有内容(如果可能很重要,我使用JQuery来设置textarea的值)。这里有一个简单的例子:立即在Javascript中更新DOM元素
for (i = 0; i <= 100; i++) {
$("textarea").html($("textarea").html() + "test" + i + "\n");
$("textarea").scrollTop(9999999)
};
这一次吐出来的所有文本到文本区域(注意:你可以看到这些例子在这个jsfiddle的结果)。这个简单的例子很容易通过创建一个超时,并使用递归函数调用补救:
f = function(i) {
if (i <= 100) {
$("textarea").html($("textarea").html() + "test" + i + "\n");
$("textarea").scrollTop(999999);
setTimeout(function() { f(i+1); }, 0);
}
};
f(1);
这个版本吐出来的是文成一次textarea的一个线,这是我想要的。但以这种方式使用超时和回调在记录设置中似乎并不实际;每次我打电话给log
时,我都必须提供一个回调函数,以便我要遵循日志调用。
有什么方法可以在没有回调的情况下达到预期的效果吗?
答
我想你可能会考虑使用:的
$("textarea").val(function(index, value) {
return value + "test" + i + "\n"
});
代替:
$("textarea").html($("textarea").html() + "test" + i + "\n");
或一般:
$("textarea").val(NEWVAL)
在你的问题的评论也指出,如果你想能够“注视”所有到达的信息你必须将它们保存在缓冲区,有这样的事情(未测试):
var buffer = []
function log(text) { buffer.push(text) }
setInterval(function(){
if (len(buffer)>0) {
$("textarea").val(function(index, value) {
return value + "\n" + buffer.shift()
});
}
},500)
答
一般的浏览器(Opera是一个例外)做JS执行和呈现在同一个线程,所以你的JS运行时除非您通过超时或间隔定时器明确控制权限,否则不会由第browser个浏览器完成渲染。
那么,你的第一个片段是如此之快,它似乎它一次添加文本... – 2011-04-24 20:46:42
你究竟想完成什么?计算机速度越快,无论如何可以观察到的影响越小。我不明白为什么你会喜欢所有额外的重绘。 – pimvdb 2011-04-24 20:48:48
伙计们,我认为他希望能够“看到”所有逐个发出的消息(因此他可以看到发生了什么),因为他必须缓冲记录的消息并打印期刊..看到我的回答 – dwarfy 2011-04-24 21:08:34