Javascript GWT bookmarket或GWT作为外部库

Javascript GWT bookmarket或GWT作为外部库,javascript,gwt,bookmarklet,Javascript,Gwt,Bookmarklet,我只是想通过向DOM添加一个脚本标记来加载GWT(Google Web Toolkit)应用程序,但是因为GWT链接器使用document.write()我找不到任何好的方法。我在不同的博客文章中发现了一些这样做的黑客,但在最新版本的GWT中,它们似乎都失败了。有没有什么合理的非侵入性方法可以做到这一点 澄清: 在主机html页面中启动GWT应用程序的正常方式: <script type="text/javascript" language="javascript" src="myapp.

我只是想通过向DOM添加一个脚本标记来加载GWT(Google Web Toolkit)应用程序,但是因为GWT链接器使用
document.write()
我找不到任何好的方法。我在不同的博客文章中发现了一些这样做的黑客,但在最新版本的GWT中,它们似乎都失败了。有没有什么合理的非侵入性方法可以做到这一点

澄清:

在主机html页面中启动GWT应用程序的正常方式:

<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script> 

每当浏览器加载javascript文件时,它也会执行其中的每一行,以构建符号表等

在您的情况下,应用程序将加载到浏览器中,加载dom后,您的GWT模块js将被加载。此时,浏览器将尝试执行GWT模块javascript的每一行,这可能会导致您先前加载的DOM出现问题

您的用例是什么?如果您的需求是有条件地加载GWT模块,那么您可以尝试以下方法: 在你的头脑中包含以下内容:

<script src="gwtmoduleloader.js"></script>
否则就悄悄地回来

当浏览器评估gwtmoduleloader.js的内容时,它可能会找到另一个脚本的document.write(在您的例子中是gwt模块),它将加载并评估该脚本。因此,这是一种有条件的负荷,可以在身体开始负荷之前实现


这就是您要找的吗?

我假设您已经在使用跨域链接器,但这并不能解决document.write的问题。如果没有,可能值得一看(对不起,没有足够的经验来说明。)

我相当确信可以采取的一种方法是:

您的bookmarklet将脚本标记添加到页面(与现在一样)

此脚本不是GWT编译器输出。它是一个普通的老javascript,向页面添加了一个IFrame,该IFrame的src指向服务器上加载GWT模块的HTML页面

大概目标是让您的GWT模块从加载到的页面中获取内容。当然,在这种情况下它不能直接这样做,因为IFrame来自与父页面不同的域

为了实现这一点,您必须使用window.postMessage和window.addEventListener在IFrame中的GWT模块和父级中的javascript存根之间进行通信(在GWT端使用JSNI)


如果您必须支持较旧的浏览器,postMessage将不起作用-但您可能可以不受哈希操作的影响-但这可能是我在实用性上划清界限的地方。

以下是迄今为止似乎有效的方法:

将以下内容添加到App.gwt.xml的顶部:

<!-- Cross site linker -->
<inherits name="com.google.gwt.core.Core" />
<add-linker name="xs" />
3) 在后面加上这一行

document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js";
因此,您基本上是用这两行替换
$doc.write

现在,您的bookmarklet将类似于:

<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a>


非常抱歉,请您重新措辞。举个例子会有帮助。@Amey签出上面的更新。谢谢只要您在站点上执行代码片段,它就应该可以工作
nocache.js
基于延迟绑定根据需要加载
cache.html
文件,并且可能不使用绝对URL。它不起作用。正如我在问题中提到的,GWT生成的myapp.nocache.js包含document.write()调用。如果它是在页面已经加载之后执行的(比如在onclick事件处理程序中调用它),那么它就不起作用了。我不知道我还能澄清多少问题,你知道bookmarklet是什么吗?在页面已经加载之后,它会将javascript注入到页面中。示例:在这个stackoverflow页面上,我正在阅读并四处查看,现在我决定运行bookmarklet。我需要将javascript注入页面。GWT的加载程序将无法工作,因为onload事件在很久以前就已经发生,document.write()将不再工作。很好的评论,谢谢。实际上,我已经想出了一个似乎有效的解决方案(我使用的是xs链接器)。我基本上替换了生成的.nocache.js中的几行,以动态插入一个脚本标记,而不是执行doc.write操作。在我确定它能工作之前,我会再测试一点…很好。似乎这个问题的“正确”解决方案是编写一个GWT链接器,它可以做正确的事情,但这一功能似乎仍在未来。更新:看起来你现在可以通过简单地使用xsiframe链接器来避免所有这些!非常好的问题和讨论,阿卜杜拉!我正试图做与您完全相同的事情,从bookmarklet添加一个GWT生成的JS。你能给我一些指向你提到的xsiframe链接器的指针吗?…我去试试上面提到的解决方案。谢谢下面是xsiframe链接器的代码:谢谢Abdullah。正如您所怀疑的,我只是使用了xsiframe链接,而且它都工作正常,无需进行任何黑客操作。谢谢
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"});');
document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js";
<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a>