2016-03-01 69 views
2

爲什麼PrimeFaces命令包含JavaScript <script>document.write("some text")</script>元素按鈕無法更新元素?瀏覽器在這樣的元素更新時「掛起」。PrimeFaces頁「掛起」

例如:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html 
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.org/ui"> 

    <h:head> 
     <title>my page</title> 
    </h:head> 

    <h:body> 
     <h:form> 
      <p:commandButton 
       id="pushMeButton" 
       value="push me" 
       update="testPanel" 
       action="#{myManagedBean.doNothing()}"> 
      </p:commandButton> 
     </h:form> 

     <p:panel id="testPanel"> 
      <script> 
       document.write("test text 1"); 
      </script> 
      <script> 
       document.write("test text 2"); 
      </script> 

      <h:outputText value="#{myManagedBean.getSomeText()}" /> 
     </p:panel> 
    </h:body> 
</html> 

按下「pushMeButton」後,瀏覽器只顯示文本「測試文本1」和「掛起」空白頁(在Firefox標籤圖標顯示該頁面仍在加載無限,但在螢火蟲中沒有主動要求)。按下按鈕後,瀏覽器接收

部分的答覆看起來是正確的:

<partial-response id="j_id1"> 
    <changes> 
     <update id="testPanel"> 
      <![CDATA[ 
      <div id="testPanel" class="ui-panel ui-widget ui-widget-content ui-corner-all" data-widget="widget_testPanel"> 
       <div id="testPanel_content" class="ui-panel-content ui-widget-content"> 
        <script> 
         document.write("test text 1"); 
        </script> 
        <script> 
         document.write("test text 2"); 
        </script> 
        some text from managed bean method getSomeText() 
       </div> 
      </div> 
      <script id="testPanel_s" type="text/javascript"> 
       PrimeFaces.cw("Panel","widget_testPanel",{id:"testPanel",widgetVar:"widget_testPanel"}); 
      </script> 
      ]]> 
     </update> 
     <update id="j_id1:javax.faces.ViewState:0"><![CDATA[1747871418605077113:5684199653317714547]]></update> 
    </changes> 
</partial-response> 

我使用PrimeFaces:5.2.5和鑽嘴魚科:2.2.8

我可以重現的行爲:Firefox的V44。 0.2和IE v11,但是在Chrome v48上,一切都按預期工作(相同頁面顯示不變)。

XHTML狙擊上面介紹的只是簡單的問題,我解決的版本。我使用「document.write」是因爲我的web應用程序從遺留系統中「導入」了一些不能更改的HTML部分(我從Liferay門戶導入菜單)。 如果我將「document.write」更改爲其他內容,例如document.getElementById('someExistingElementId').innerHTML = 'New text';一切正常。

它看起來像BalusC 的評論:「我認爲我看到的根本原因。IE6/7/8可惜不運行嵌入的腳本文件撰寫時,()是被用來代替DOM」http://forum.primefaces.org/viewtopic.php?f=3&t=18937&start=20 )與我的問題有關,但我不明白爲什麼它不起作用,以及是否有可能使它在現代瀏覽器上工作。

+0

我不知道我理解你的問題。在您的示例中,腳本中沒有任何更新。此外,commandButton不會在bean中調用任何操作。如果你讓代碼更接近你實際擁有的東西,它可能會更有用。 – Ced

+0

我更新了我的示例:我添加了調用空的託管bean方法的操作,並將h:outputText添加到我的面板並相應地更新了響應。 – Palladium

回答

3

的問題不直接關係到PrimeFaces或JSF - 這是JavaScript的工作原理。

「如果在HTML文檔完全加載後使用它,它將刪除 所有現有的HTML。」 (http://www.w3schools.com/jsref/met_doc_write.asp

我可以使用HTML和JS重現類似的情況:

<!DOCTYPE html> 
<html> 
    <body>  
     <p>Click the button to trigger a function</p>  
     <button onclick="myFunction()">Click me</button> 
     <script> 
      function myFunction() { 
       document.write("test text 1"); 
      } 
     </script>  
    </body> 
</html> 
這已經加載

部分更新的更新文件 - 這就是爲什麼只有「測試文本1」後按鈕提交點擊。因爲在執行第一個<script>document.write("test text 1");<script>之後,所有文檔都會被覆蓋。

火狐「掛起」,因爲「document.close」當時不叫(如文件輸出流未打開「文件撰寫」將其打開,因此有必要將其關閉)。

所以恢復是:它是不可能使用document.write(...);在JSF頁面,如果頁面的一部分可以用Ajax調用進行更新。

在大多數情況下document.write(...)應避免在JSF頁面,因爲它並不總是可能控制頁面的一部分將被更新。例如,OmniFace FullAjaxExceptionHandler將在異常之後執行update =「@ all」,因此錯誤頁面不能有任何document.write(...)語句。