2010-01-05 125 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