我想使用GWT插入FlowPanel,HTMLPanel里面和iframe等GWT Widgets。我找到了this帖子,它将内容作为字符串插入到iFrame中。但是,当我想要集成其他面板和小部件时,这没有用。
我找到了如何以编程方式将GWT Widgets和Panel插入GWT。我是这样做的:
public interface Resources extends ClientBundle {
@Source({Css.DEFAULT_CSS})
Css css();
}
public interface Css extends CssResource {
String DEFAULT_CSS = "test/client/app/start/StartView.gss";
String outerBox();
String iframe();
String test();
}
@UiField(provided = true)
Resources resources;
@UiField(provided = true)
Messages messages;
@Inject
public StartView(final Binder binder, Resources resources, Messages messages)
{
this.resources = resources;
resources.css().ensureInjected();
this.messages = messages;
initWidget(binder.createAndBindUi(this));
final IFrameElement iframe = Document.get().createIFrameElement();
FlowPanel innerBox = new FlowPanel() {
@Override
protected void onLoad() {
super.onLoad();
FlowPanel p1 = new FlowPanel();
p1.addStyleName(resources.css().test());
HTMLPanel panel = new HTMLPanel("Hello World!");
panel.setStyleName(resources.css().test()); // does not work
p1.add(panel);
final Document doc = iframe.getContentDocument();
BodyElement body = doc.getBody();
body.appendChild(p1.getElement());
panel.setStyleName(resources.css().test()); // does not work
p1.getElement().addClassName(resources.css().test()); // does not work
}
};
}
我的uiBinder:
<ui:with type="test.client.app.start.StartView.Resources" field="resources" />
<ui:with type="test.client.messages.Messages" field="messages" />
<g:FlowPanel ui:field="outerPanel" addStyleNames="{resources.css.outerBox}">
</g:FlowPanel>
前一代码将GWT面板插入iframe。问题是我无法设置任何CSS样式。即使我将样式设置为:
panel.setStyleName(resources.css().test()); // does not work
p1.getElement().addClassName(resources.css().test()); // does not work
两种变体都不起作用。我知道我可以在iframe文档的头部注入一个通用的css文件,但我想使用GWT资源。
如何使用CSS / GSS资源为iframe中的面板设置样式?
答案 0 :(得分:2)
我建议使用IFrameElement以编程方式向iframe添加内容,并使用getContentDocument()
检索iframe文档,以便附加新内容。
顺便说一下,你仍然可以在view.ui.xml:
中使用这样的UIBinder <iframe ui:field="container"/>
并在你的View.java中:
@UiField IFrameElement container;
关于CSS我认为主要问题是iframe就像一个沙盒,并且不与父文档共享信息。我最好的猜测是你应该从父母那里克隆你的<link/>
或<style/>
元素并将其附加到孩子的<head/>
。
最终的解决方案是:
Event.sinkEvents(iframe, Event.ONLOAD);
Event.setEventListener(iframe, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
StyleElement style = Document.get().createStyleElement();
style.setInnerText(resources.css().getText());
iframe.getContentDocument().getHead().appendChild(style);
ParagraphElement pEl = Document.get().createPElement();
pEl.setInnerText("Hallo World");
pEl.addClassName(resources.css().whatever());
iframe.getContentDocument().getBody().appendChild(pEl);
}
});
事件监听器是必要的,以便从iframe中检索文档,您应该等待框架加载它,即使它是 about:blank 。
答案 1 :(得分:0)
<iframe>
不能包含子元素(它们将被忽略),因为它实际上是嵌套在文档中的浏览器窗口。您必须使用其src
属性来指定要加载的资源。