所以在直接查看 twitter 小部件 javascript 代码后,我看到可以传入一个 id,因此可以使用现有元素。太糟糕了 twitter 并没有真正记录所有可用的不同选项(至少没有在我上面发布的页面上),我可能更早发现了这一点。
这是一个示例复合小部件,它将插入一个 twitter 小部件并在 GWT 中工作,我已经在 GWT 2.4 中测试了这段代码,它在 Firefox 6、Chrome 16 和 IE9 中工作(尽管 IE 在我的环境中有一些奇怪的样式问题)。
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
public class TwitterWidget extends Composite {
private JavaScriptObject widgetJsObj = null;
private final FlowPanel twPanel;
private final boolean destroyOnUnload;
public TwitterWidget() {
this(true);
}
public TwitterWidget(boolean destroyOnUnload) {
this.destroyOnUnload = destroyOnUnload;
twPanel = new FlowPanel();
twPanel.getElement().setId(DOM.createUniqueId());
initWidget(twPanel);
}
@Override
protected void onLoad() {
super.onLoad();
Callback<Void, Exception> callback = new Callback<Void, Exception>() {
@Override
public void onSuccess(Void result) {
if (nativeEnsureTwitterWidgetJsLoadedAndSetToWnd()) {
renderAndStart();
} else {
GWT.log("even though success has been called, the twitter widget js is still not available");
// some logic maybe keep checking every second for 1 minute
}
}
@Override
public void onFailure(Exception reason) {
// TODO Auto-generated method stub
GWT.log("exception loading the twitter widget javascript", reason);
}
};
boolean isTwitterWidgetAvailable = nativeEnsureTwitterWidgetJsLoadedAndSetToWnd();
if (isTwitterWidgetAvailable) {
renderAndStart();
} else {
ScriptInjector.fromUrl("http://widgets.twimg.com/j/2/widget.js")
.setWindow(ScriptInjector.TOP_WINDOW)
.setCallback(callback)
.inject();
}
}
@Override
protected void onUnload() {
super.onUnload();
if (widgetJsObj!=null) {
// need to manually destroy so that attached events get removed
if (destroyOnUnload) {
nativeDestroyTwitterWidget(widgetJsObj);
} else {
nativeStopTwitterWidget(widgetJsObj);
}
}
}
private native JavaScriptObject nativeRenderStartTwitterWidget(String domId) /*-{
var twObj = new $wnd.TWTR.Widget({
version: 2,
id: domId,
type: 'search',
search: 'rainbow',
interval: 30000,
title: 'It\'s a double rainbow',
subject: 'Across the sky',
width: 250,
height: 300,
theme: {
shell: {
background: '#8ec1da',
color: '#ffffff'
},
tweets: {
background: '#ffffff',
color: '#444444',
links: '#1985b5'
}
},
features: {
scrollbar: false,
loop: true,
live: true,
behavior: 'default'
}
}).render().start();
return twObj;
}-*/;
private native boolean nativeEnsureTwitterWidgetJsLoadedAndSetToWnd() /*-{
// this only works when TWTR has been properly loaded to $wnd directly
if (!(typeof $wnd.TWTR === "undefined") && !(null===$wnd.TWTR)) {
return true;
}
return false;
}-*/;
private native JavaScriptObject nativeStopTwitterWidget(JavaScriptObject twObj) /*-{
return twObj.stop();
}-*/;
private native JavaScriptObject nativeDestroyTwitterWidget(JavaScriptObject twObj) /*-{
return twObj.destroy();
}-*/;
private void renderAndStart() {
widgetJsObj = nativeRenderStartTwitterWidget(twPanel.getElement().getId());
// you can call other native javascript functions
// on twitWidgetJsObj such as stop() and destroy()
}
}