2011-02-03 64 views
2

我正在研究一个具有页面结构树的CMS,因此我试图模拟用于浏览其C驱动器的Windows资源管理器。因此,最初我在根级别列出页面,并使用onClick事件和AJAX,单击根页面将显示下面的页面,在我创建/分配的DIV中。在使用innerHTML插入Ajax响应之前,浏览器不更新文本

所有工作正常,我有一个动画加载gif显示在另一个DIV而xmlhttp.send正在运行,当if (xmlhttp.readyState==4 && xmlhttp.status==200)为真时关闭。

问题是,当有大量的子页面(1000左右,是的,客户端创建它们),AJAX完成,它得到document.getElementById(DivId).innerHTML = xmlhttp.responseText;,这导致gif停止旋转。所以我GOOGLE了,看来这是一个浏览器问题。

所以我想,我会在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); 
} 

回答

0

你真的应该使用一个框架。我最近使用内置于extjs中的ajax treeview来创建几乎相同的东西。相信我这会为你节省很多头痛。跨浏览器dom是PITA。

我知道这并不回答您的具体问题,但请听我的建议!

http://dev.sencha.com/deploy/dev/examples/tree/reorder.html

+0

感谢拜伦是exjs像jQuery libary?看着这些是我的下一个清单 – KevInSol 2011-02-03 19:50:21

+0

是的,就像jquery,但更全功能。这是你可以在其中做的事情。 http://dev.sencha.com/deploy/dev/examples/ – 2011-02-03 20:28:15

0

的唯一解决方案是重新设计。 - 不,它不是,但你真的应该 - 阅读;)

动画gif停止动画的原因是因为浏览器正在使用它所有的肌肉来追加新的元素到DOM和重新呈现/完成后绘制页面。根本没有cputime让它动画gif。

计算机/浏览器越慢,您将看到此问题的情况越多,但如果您构建的页面具有足够的元素,则可以在4ghz计算机上的谷歌浏览器中进行此操作。

浏览器在javascript/DOM制作/渲染/绘画方面的本质是一个单线程的野兽,因此它一次只能做一件事。

它试图弥补这一点,将复杂的操作分解成片,然后运行这些片以使它看起来像它可以一次完成多件事情(就像操作系统在单核机上一样,尽管简单得多)

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

至于没有出现的文字:

如果你希望做一个小的DOM操作生效(如插入文本),一个你做一个大的DOM操纵之前,您需要在浏览器处理这个作为两个单独的切片(它不想做,因为DOM操作和随后的重新渲染/重新绘画是非常cpu成本高)

要做到这一点,打破JavaScript的callstack通过使用setTimeout

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

通常它是足够做setTimeout具有零延迟基础,因为本身setTimeout打破了调用堆栈,但在某些情况下,你需要一个小的延迟 - 玩它,并找到自己的甜点:)

例如:

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