3

我需要能够在 Echo2 环境中随时加载和启动 GWT 应用程序。我的第一种方法是在客户端-服务器同步中加载和执行 nocache.js,使用

var script = document.createElement("script");
script.setAttribute("src",javascriptURI);
script.setAttribute("type","text/javascript");
document.getElementsByTagName('body')[0].appendChild(script);

这个调用基本上是有效的,但是当脚本被执行时,它在一个 EMPTY 文档而不是 Echo2 应用程序的当前文档上运行。脚本是否首先以某种方式初始化,或者是否需要任何事件?

如果 GWT 应用程序/脚本包含在应用程序的启动 HTML 中,则它可以正常工作,因此我假设 GWT 应用程序是正确的。GWT 应用程序的原始独立 HTML 在正文中也有 HTML 脚本标记。

4

1 回答 1

1

问题是,nocache.js 文件中的 dowcument.write 调用仅在文档尚未完成加载时才有效。否则 document.write 将覆盖整个文档。

因此 document.write 调用必须被 DOM 的 createElement 方法替换:

对于添加带有标记 id 的脚本的第一个代码:

var script = document.createElement("script");
script.setAttribute("id", markerId);
$doc_0.getElementsByTagName("body")[0].appendChild(script);

对于第二部分(几乎在 nocache.js 的末尾)。将“app”替换为您的应用程序名称:

try {
    var script = document.createElement("script");
    script.setAttribute("defer", "defer");
    script.innerHTML = "app.onInjectionDone('app')";
    $doc_0.getElementsByTagName("body")[0].appendChild(script);
} catch (e) {
    // Fallback if we want to use the original html page without embedding in IE
    $doc_0.write('<script defer="defer">app.onInjectionDone(\'app\')<\/script>');
}

因此,这是必须在 gwt 生成的代码中修补的部分。现在,当用户单击按钮时加载并启动应用程序的 html 页面:

<html> 
  <head> 
    <!-- base url --> 
    <base href="http://localhost:8080/app/" /> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <link type="text/css" rel="stylesheet" href="static-gwt.css"> 
    <title>APP</title> 
    <script type="text/javascript"> 

    function startApp() {
        if (document.createElement && document.getElementsByTagName) {
          var script = document.createElement('script');
          script.type = 'text/javascript';
          script.src = 'app/app.nocache.js';
          var heads =document.getElementsByTagName('body');
          if (heads && heads[0]) {
            heads[0].appendChild(script);
            triggerAppStart();
          }
        }
    }

    function triggerAppStart(){
        try{
        app.onInjectionDone('app');
        if ( !document.createEventObject ) {
            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("DOMContentLoaded", true, true);
            document.dispatchEvent(evt);
           }
        } catch ( e ) {
        window.setTimeout('triggerAppStart()', 100 );
       } 
    }

</script> 
  </head> 
  <body> 
    <input type="button" onclick="startApp();return false;"> 
  </body> 
 </html> 

我知道这不是最好的解决方案,但它是迄今为止唯一可行的方法。

于 2010-04-09T10:40:23.407 回答