【问题标题】:Waiting for DOM to load in JSNI GWT等待 DOM 在 JSNI GWT 中加载
【发布时间】:2012-05-25 17:56:54
【问题描述】:

我目前遇到的问题是 javascript 似乎在 DOM 完全加载之前正在执行。我为什么这么说?取以下代码:

var $r = $wnd.Raphael("container", 640, 480);

// Creates pie chart at with center at 320, 200,
// radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
$r.piechart(320, 240, 100, [ 55, 20, 13, 32, 5, 1, 2 ]);

返回一个 Javascript 异常:'f is null'。这似乎表明无法识别容器名称。

如果指定绝对坐标,则饼图渲染得很好。如果我在 Chrome 控制台中使用前面的代码(在所有加载后)它有效,将饼图加载到容器标签中。

我尝试将代码块包装在 JQuery 调用中:

$wnd.jQuery(function($) {
            // Creates canvas 640 × 480 at 10, 50
            var $r = $wnd.Raphael("container", 640, 480);
            // Creates pie chart at with center at 320, 200,
            // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
            $r.piechart(320, 240, 100, [ 55, 20, 13, 32, 5, 1, 2 ]);
    });

...而且没有骰子。

有什么我可以尝试的想法吗?

编辑:

这是我调用 JSNI 方法的方式/位置。以下是相关的View代码。

public class WidgetSamplerView extends AbstractPanelView implements
                WidgetSamplerPresenter.Display { 

private FlexTable mainPanel;

public WidgetSamplerView() {
        super();

            mainPanel = new FlexTable();

            HTML container = new HTML();
        container.getElement().setAttribute("style",
                "width:700px;height:700px");
        container.getElement().setId("container");

        mainPanel.setWidget(0, 1, container);

        MyRaphaelWrapper.pieChart(); // JSNI Call

        setWidget(mainPanel);
    }
}

【问题讨论】:

  • 只是猜测:也许 Raphael 试图查看错误的 DOM?我会尝试 $wnd.Raphael($doc.getElementById("container"), 640, 480);
  • 我们需要看更多的上下文代码,比如JSNI调用。您是否在适当的阶段(onLoad、onAttach、onRender 等)调用 JSNI 包装方法?
  • @StefanHaustein 没有骰子,它返回'f is null'。无论如何感谢您的评论。
  • @EliranMalka 在将一堆其他小部件添加到应用程序的主容器面板后,我只是在 Presenter 中静态调用它。
  • 请附上演示者代码,这将为我们(和您)提供更多线索。

标签: javascript gwt dom jsni


【解决方案1】:

您必须确保仅在激活onLoad() 时调用 JSNI 方法,以验证小部件已加载。

请参阅another answer of mine on best practices for creating and initializing widgets,以获取快速参考。

基本思想是覆盖小部件上的onLoad() 并在那里调用任何加载功能:

public class MainPanel extends FlexTable {

    private Element container;

    public MainPanel() {

        container = DOM.createDiv();
        container.setId("container");

        // this is required by the Widget API to define the underlying element
        setElement(container);
    }

    @Override
    protected void onLoad() {
        super.onLoad();

            MyRaphaelWrapper.pieChart(); // JSNI Call
        }
    }
}

【讨论】:

  • 我依靠 JQuery 来检查 DOM 完成情况。在您发布之前几分钟,我得到了这个确切的解决方案,但无论如何,这是要走的路!
【解决方案2】:

我怀疑 Raphael 在内部做了以下事情:

document.getElementById("container");

如果您使用标准设置编译 GWT 应用程序,则代码会加载到 iframe 中。这就是为什么你必须使用 $wnd 而不是 window 和 $doc 而不是 document。它们指向主窗口。

您是如何包含其他 javascript 库的?因为 Raphael 可能正在查看错误的 DOM(iframe 的 dom)。你能用这样的方法直接将元素传递给 rapahel 吗?

var c = $doc.getElementById("container");
$wnd.Raphael(c, ..);

【讨论】:

  • 'f 为空'。不过感谢您的评论:)
猜你喜欢
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 2022-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多