Javascript 浏览器在插入带有innerHTML的Ajax响应之前不更新文本

Javascript 浏览器在插入带有innerHTML的Ajax响应之前不更新文本,javascript,Javascript,我正在开发一个具有树状页面结构的CMS,因此我尝试模拟一个用于浏览其C驱动器的Windows资源管理器。因此,最初我在根级别列出页面,并使用onClick事件和AJAX,单击根页面将在其下方显示页面,在我为此创建/分配的DIV中 一切正常,当xmlhttp.send运行时,我在另一个DIV中显示了一个加载gif的动画,如果(xmlhttp.readyState==4&&xmlhttp.status==200)为true,则该动画将在时关闭 问题是,当有大量子页面(大约1000个子页面,是的,客户

我正在开发一个具有树状页面结构的CMS,因此我尝试模拟一个用于浏览其C驱动器的Windows资源管理器。因此,最初我在根级别列出页面,并使用onClick事件和AJAX,单击根页面将在其下方显示页面,在我为此创建/分配的DIV中

一切正常,当xmlhttp.send运行时,我在另一个DIV中显示了一个加载gif的动画,如果(xmlhttp.readyState==4&&xmlhttp.status==200)为true,则该动画将在
时关闭

问题是,当有大量子页面(大约1000个子页面,是的,客户机创建了它们)时,AJAX就完成了,它会进入
document.getElementById(DivId).innerHTML=xmlhttp.responseText这会导致gif停止旋转。所以我用谷歌搜索了一下,这似乎是一个浏览器问题

所以我想,我将在AJAX调用期间使用gif,并在浏览器呈现新的innerHTML时显示等待文本。然而,尽管需要几秒钟的时间,这个文本永远不会显示,我只看到冻结的gif,然后一旦渲染,“完成”文本

如果我注释掉“完成”行,等待文本确实会显示出来

代码如下:

function getPages(page_id, DivId)
{
    var loadingicon_div = "page_" + page_id + "_loadingicon";
    var loading_icon = 'image here, not allowed to post images..'; 

    document.getElementById(loadingicon_div).innerHTML = loading_icon;

    xmlhttp = new GetXmlHttpObject();
    xmlhttp.onreadystatechange = function() 
                    { 
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
                        {
                            document.getElementById(loadingicon_div).innerHTML = "Retrieved pages from the server, please wait while your browser displays them ...";
                            document.getElementById(DivId).innerHTML = xmlhttp.responseText;
                            document.getElementById(DivId).style.padding="5px";
                            document.getElementById(loadingicon_div).innerHTML = "done";
                        }
                    }

    var url="tree_ajax.php";

    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
}

你真的应该使用一个框架。我最近使用内置在extjs中的ajax treeview实现了几乎相同的功能。相信我,这会帮你省去很多麻烦。跨浏览器dom是一种PITA

我知道这不能回答你的具体问题,但请听我的建议


你真的应该使用一个框架。我最近使用内置在extjs中的ajax treeview实现了几乎相同的功能。相信我,这会帮你省去很多麻烦。跨浏览器dom是一种PITA

我知道这不能回答你的具体问题,但请听我的建议

解决这个问题的唯一办法是重新设计。-不,不是,但你真的应该——继续读下去;)

已设置动画的gif停止设置动画的原因是,浏览器正在竭尽全力将新元素添加到DOM中,并在完成后重新渲染/重新绘制页面。根本没有cputime可供它设置gif动画

计算机/浏览器的速度越慢,你就会越容易发现这个问题,但是如果你构建了一个包含足够元素的页面,你可以在4ghz计算机上的google chrome上实现这一点

当涉及到javascript/DOM制作/渲染/绘制时,浏览器本质上是一个单线程的野兽,因此它一次只能做一件事

它试图通过将复杂的操作分解为多个部分来弥补这一缺陷,然后以一种使其看起来可以同时完成多个任务的方式运行这些部分(与单核机器上的操作系统非常相似,尽管要简单得多)

但是,一旦获得了足够复杂的dom结构,重新渲染/重新绘制片段就会变得非常大,以至于浏览器在执行时似乎会冻结

至于没有出现的文本:

如果希望在执行大型DOM操作之前使小型DOM操作生效(如插入文本),则需要使浏览器将其视为两个单独的片(它不希望这样做,因为DOM操作和随后的重新渲染/重新绘制非常耗费cpu)

为此,请使用
setTimeout
在javascript中断开调用堆栈

这将允许浏览器在下一次DOM操作和随后的重新渲染/重新绘制之前执行重新渲染/重新绘制

通常情况下,使用零延迟执行
setTimeout
就足够了,因为
setTimeout
本身会破坏调用堆栈,但在某些情况下,您需要一个小的延迟-使用它并找到您的最佳点:)

例如:

//do small DOM manipulation here
setTimeout(function(){
  //do major DOM manuipulation here
},0);
唯一的解决办法是重新设计不,不是,但你真的应该——继续读下去;)

已设置动画的gif停止设置动画的原因是,浏览器正在竭尽全力将新元素添加到DOM中,并在完成后重新渲染/重新绘制页面。根本没有cputime可供它设置gif动画

计算机/浏览器的速度越慢,你就会越容易发现这个问题,但是如果你构建了一个包含足够元素的页面,你可以在4ghz计算机上的google chrome上实现这一点

当涉及到javascript/DOM制作/渲染/绘制时,浏览器本质上是一个单线程的野兽,因此它一次只能做一件事

它试图通过将复杂的操作分解为多个部分来弥补这一缺陷,然后以一种使其看起来可以同时完成多个任务的方式运行这些部分(与单核机器上的操作系统非常相似,尽管要简单得多)

但是,一旦获得了足够复杂的dom结构,重新渲染/重新绘制片段就会变得非常大,以至于浏览器在执行时似乎会冻结

至于没有出现的文本:

如果希望在执行大型DOM操作之前使小型DOM操作生效(如插入文本),则需要使浏览器将其视为两个单独的片(它不希望这样做,因为DOM操作和随后的重新渲染/重新绘制非常耗费cpu)

为此,请使用
setTimeout
在javascript中断开调用堆栈

这将允许浏览器在下一次DOM操作和随后的重新渲染/重新绘制之前执行重新渲染/重新绘制

通常情况下,使用零延迟执行
setTimeout
就足够了,因为
setTimeout
本身会破坏调用堆栈,但在某些情况下,您需要一个小的延迟-使用它并找到您的最佳点:)

例如:

//do small DOM manipulation here
setTimeout(function(){
  //do major DOM manuipulation here
},0);

谢谢你,马丁。现在在家,明天就试试吧。谢谢马丁。现在在家里,所以明天我会试试。谢谢Byron,exjs和jquery一样是图书馆吗?看看这些我