2016-03-01 68 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(...)语句。