立即在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时,我都必须提供一个回调函数,以便我要遵循日志调用。

有什么方法可以在没有回调的情况下达到预期的效果吗?

+1

那么,你的第一个片段是如此之快,它似乎它一次添加文本... – 2011-04-24 20:46:42

+0

你究竟想完成什么?计算机速度越快,无论如何可以观察到的影响越小。我不明白为什么你会喜欢所有额外的重绘。 – pimvdb 2011-04-24 20:48:48

+0

伙计们,我认为他希望能够“看到”所有逐个发出的消息(因此他可以看到发生了什么),因为他必须缓冲记录的消息并打印期刊..看到我的回答 – dwarfy 2011-04-24 21:08:34

我想你可能会考虑使用:的

$("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个浏览器完成渲染。