2010-01-05 45 views
0

我有一个严格基于浏览器的javascript & xlst应用程序。它通常在本地机器上使用,但有时通过Apache访问。window.onready = function()在IE中失败

主页面是content.html,其内容动态变化。在一种情况下,一个页面中的href会打开一个新窗口,并最终执行下面的代码来设置一个onready函数,目的是获取新窗口的内容。

这在几乎所有情况下都可以使用。它适用于Firefox的所有情况。它甚至可以在本地运行时用于IE的所有情况下(例如file:/// C:/Program%20Files/Apache%20Software%20Foundation/Apache2.2/htdocs/hlic/index.html)。

我的问题是,当通过Apache访问IE时,我只是得到一个空白窗口。它的行为就像从来没有开启函数。但是,如果我添加警报(“火警”),则会显示警报,之后,我的窗口内容会显示出来。那么为什么它只适用于警报?我还能做些什么才能让内容显示出来。任何帮助将不胜感激。

下面的代码:

/* 
* PresentStreamInNewBrowser 
* 
*  Creates a new browser window and fills with 
*  provided content stream. Also sizes the 
*  window to either default dimensions or to any  
*  supplied dimensions. 
* 
*  A close and a print button are added to the bottom 
*  of the content stream. 
* 
*  Inputs: 
*   pageStream - content stream to display 
*    in new window. 
*   height, width, top, left - dimensions 
*    for the newly opened window. (optional) 
* 
*/ 
function Presenter_PresentStreamInNewBrowser(pageStream, height, width, top, left) 
{ 
    // set the features 
    var features = "height=" + height; 
     features += ",width=" + width; 
     features += ",top=" + top; 
     features += ",left=" + left; 
     features += ",scrollbars=yes"; 
     features += ",resizable=yes"; 

    // open the window 
    var presenter = this; 
    var newWindow = window.open(
     app.NormalizeURI("deview/frames/content.html"), '', features); 

    // the rest of the code executes when the content window 
    // calls its onready function, after it has loaded 
    newWindow.onready = function() { 



     var doc = newWindow.document; 

     // create stylesheet links if applicable 
     for(var i = 0; i < pageStream.stylesheet.length; i++) { 
      var linkElement = doc.createElement("link"); 
      linkElement.rel = "stylesheet"; 
      linkElement.href = pageStream.stylesheet[i]; 
      doc.getElementsByTagName("head")[0].appendChild(linkElement); 
     } 

     // insert content 
     doc.body.innerHTML = ""; 
     doc.body.appendChild(pageStream.content.importIntoDocument(doc)); 
     doc.body.appendChild(doc.createElement("br")); 

     // Handle generation of special pages. 
     presenter.AddGeneratedContent(doc); 

     // add a close button 
     var selectionString = 
     "displayStrings/promptStrings/promptString[@id='close_button_anchor']"; 
     var buttontext = app.displayStringsDOM.selectSingleNode(
     selectionString).firstChild.nodeValue; 
     var closeButtonElement = doc.createElement("button"); 
     closeButtonElement.id = "closebutton"; 
     closeButtonElement.className = "addonbutton"; 
     closeButtonElement.onclick = "javascript:window.close()"; 
     closeButtonElement.value = buttontext; 
     doc.body.appendChild(closeButtonElement); 

     // add a print button 
     selectionString = 
     "displayStrings/buttonLabelStrings/buttonLabelString[@id='print_button_anchor']"; 
     buttontext = app.displayStringsDOM.selectSingleNode(
     selectionString).firstChild.nodeValue; 
     var printButtonElement = doc.createElement("button"); 
     printButtonElement.id = "printbutton"; 
     printButtonElement.className = "addonbutton"; 
     printButtonElement.onclick = "javascript:window.print()"; 
     printButtonElement.value = buttontext; 
     doc.body.appendChild(printButtonElement); 

     // close up shop 
     newWindow.document.body.appendChild(
     newWindow.document.createElement("br")); 
     newWindow.document.title = '-'; 

     // add some language dependent text 
     presenter.AddButtonLabel(doc); 
     presenter.AddExamLabels(doc); 

     //alert("fire"); 
    }   
} 

回答

1

也许你可以尝试检查文档的readyState,像

var newWindowReadyFired = false; 

newWindow.onready = function() { 
    if (newWindowReadyFired) return; //just in case race condition got us in here twice 
    newWindowReadyFired = true; 

    //....the rest of your event handler 
} 

function chkFunc() { 
    if (newWindowReadyFired) return; //magic already done 

    if (newWindow.document && newWindow.document.readyState == 4) { 
    newWindow.onready(); 
    } else { 
    setTimeout(chkFunc,"100"); //wait and try again 
    } 
} 
chkFunc(); 

不能保证这会工作,但也许值得一试?

+0

这非常有帮助。谢谢! 对于我的情况,我实际上可以从同一页面启动多个弹出窗口,全部使用相同的代码(content.html)。所以我只是不检查onready函数中的newWindowReadyFired。 – 2010-01-05 18:34:09

+0

实际上,它应该仍然是安全的 - “javascript闭包”(范围,允许内部方法访问外部方法的变量)*应该*表示该变量的一个新实例为您每次打电话时创建Presenter_PresentStreamInNewBrowser()方法,并在检查中引用正确的实例。我90%确定这一点(这也意味着10%的不确定性,所以你仍然想以某种方式自己检查一下,也许通过在alert中显示var的值并在第二个窗口中检查它加载) – Graza 2010-01-05 20:13:12

1

最好的猜测是,ready事件已在目标窗口的处理程序分配的时间已经解雇 - 换句话说,你打比赛的条件。

我使用的解决方案是在content.html东西本身 content.html内执行回调无论是在在线使用window.opener JavaScript中的父窗口或在ready处理是,在您的使用情况下是可行的?

+0

+1,很棒的分析 – orip 2010-01-05 17:11:43

+0

感谢您的回复。这个问题似乎与竞争条件有关。 – 2010-01-05 18:31:26