【问题标题】:Add GWT Widgets inside an iFrame in UIBinder?在 UIBinder 的 iFrame 中添加 GWT 小部件?
【发布时间】:2016-01-05 05:37:36
【问题描述】:

我想在内部插入 GWT 小部件,如 FlowPanel、HTMLPanel 和使用 GWT 的 iframe。我发现this 帖子将内容作为字符串插入到 iFrame 中。但是,当我想集成其他面板和小部件时,这无济于事。

我了解了如何以编程方式将 GWT 小部件和面板插入 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 内的面板设置样式?

【问题讨论】:

  • 你真的需要 iFrame 吗?我认为新创建的 iFrame 与您的 GWT 应用程序具有不同的域。所以你会遇到 SOP 的问题。我建议使用 div - 如果可能的话。
  • 我想创建一个嵌入到不同页面的插件。所以我只能用iframe来保证我自己的css。
  • 不同的页面是否为您的插件提供了一个区域?不同的页面与您的应用无关?
  • 请在此处查看聊天小部件:livechatinc.com 这是一个很好的例子。您需要一个 iframe,以使页面的 css 不会覆盖或影响您的 css。

标签: javascript java html iframe gwt


【解决方案1】:

我建议使用 IFrameElement 以编程方式将内容添加到 iframe 并使用 getContentDocument() 检索 iframe 文档以附加新内容。

顺便说一句,你仍然可以像这样在 view.ui.xml 中使用 UIBinder:

 <iframe  ui:field="container"/>

在你的 View.java 中:

 @UiField IFrameElement container;

关于 CSS 我认为主要问题是 iframe 就像一个沙箱,不与父文档共享信息。我最好的猜测是,您应该从父级克隆您的 &lt;link/&gt;&lt;style/&gt; 元素并将其附加到子级的 &lt;head/&gt; 中。

最终的解决方案是:

    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

【讨论】:

  • 请看我的编辑。如何从 iframe 中的 GWT 资源中获取 css?
  • 我的“从父级克隆你的链接元素”是什么意思?顺便说一句,你的解决方案不起作用你不能做container.getContentDocument()。这会导致错误。
  • 奇怪,因为这正是你正在做的。无论如何,我的意思是在父级中您应该拥有 CSS,但随后您将类应用于 iframe 内的元素。在 iframe 中,CSS 是不可见的,唯一的方法是将相同的 CSS 克隆到 iframe 中。想象在父级中 CSS 包含为 &lt;link rel="stylesheet" type="text/css" href="urltocss" charset="utf-8"&gt; 我会将此元素复制到 iframe 头中。
  • 我知道你的意思。但在我的父母中,我没有main.css。我使用 GWT CSSResources。所以 GWT 内联了 css。有没有办法在 iframe 中使用它?
  • 试试MyResources.INSTANCE.css().ensureInjected();
【解决方案2】:

&lt;iframe&gt; 不能包含子元素(它们将被忽略),因为它实际上是嵌套在文档中的浏览器窗口。您必须使用其src 属性来指定要加载的资源。

【讨论】:

猜你喜欢
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2016-05-14
  • 1970-01-01
  • 2014-08-31
  • 2011-02-08
  • 2011-07-04
相关资源
最近更新 更多