我只是想通过向DOM添加脚本标记来加载GWT(Google Web Toolkit)应用程序,但是因为GWT链接器使用document.write()
我无法找到任何好方法。我在各种博客文章中发现了一些黑客,但他们似乎都失败了最新版本的GWT。我想到任何合理的非侵入性方法吗?
澄清:
在主机html页面中启动GWT应用程序的正常方式:
<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script>
这当然会在页面加载后立即启动。我想稍后再这样做:
function startapp() {
var head = document.getElementsByTagName('head');
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', 'myapp.nocache.js');
head[0].appendChild(s);
}
答案 0 :(得分:5)
到目前为止似乎有效:
将其添加到App.gwt.xml的顶部:
<!-- Cross site linker -->
<inherits name="com.google.gwt.core.Core" />
<add-linker name="xs" />
使用上述设置编译您的应用后,修改(或复制)生成的app.nocache.js,如下所示:
1)评论最后的$doc.write...
声明
2)从刚刚注释掉的$doc.write
语句中复制此部分并对其进行评估。例如:
eval('window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),' + 'type: "end"});' + 'window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),' + 'type: "moduleRequested"});');
3)在此之后添加此行。
document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js";
所以你基本上用这两行代替$doc.write
。
现在,您的书签类似于:
<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a>
答案 1 :(得分:1)
我假设您已经在使用跨域链接器,但这并不能解决您对document.write的问题。如果没有,可能值得一看(抱歉,没有足够的经验可以说。)
我相信可以使用的一种方法是:
您的bookmarklet会向页面添加脚本标记(现在为止)
此脚本不是GWT编译器输出。这是一个普通的javascript,它为页面添加了一个IFrame,并且该IFrame的src指向服务器上加载GWT模块的HTML页面。
据推测,目标是让您的GWT模块从加载到的页面中取出内容。当然,在这种情况下它不能直接执行此操作,因为IFrame来自与父页面不同的域。
为了完成这项工作,您必须使用window.postMessage和window.addEventListener在IFrame中的GWT模块和父级的javascript存根之间进行通信(在GWT端使用JSNI。)
如果你必须支持旧的浏览器,postMessage将不起作用 - 但你可能能够摆脱散列操作 - 但这可能是我在实用性方面划清界线的。
答案 2 :(得分:0)
每当浏览器加载javascript文件时,它也会执行它的每一行以构建符号表等。
在您的情况下,应用程序在浏览器中加载,并在加载dom后,您的GWT模块js被加载。此时,浏览器将尝试执行GWT模块javascript的每一行,可能导致您之前加载的DOM进行折腾。
您的用例究竟是什么?如果您的要求有条件地加载GWT模块,那么您可以尝试这样的事情: 将此包含在您的脑海中:
<script src="gwtmoduleloader.js"></script>
在这里,gwtmoduleloader.js
实际上是一个servlet,它将保存逻辑以确定是否要加载gwt模块。
如果要加载GWT模块,则sevlet可以打印
document.write('<script src="myapp.nocache.js"></script>')
或者默默地回来。
当浏览器评估gwtmoduleloader.js的内容时,它可能会找到另一个脚本(在您的情况下是gwt模块)的document.write,它将加载并评估。因此,这是一个条件载荷,可以在身体开始加载之前实现。
这是你在找什么?