【问题标题】:GWT Node or Element listen to onAttach eventGWT 节点或元素监听 onAttach 事件
【发布时间】:2016-07-18 23:02:33
【问题描述】:

有没有办法处理 GWT 节点中的 onAttach 事件?我想我可以这样做:

Node myDiv = DOM.createDiv();
Magic.setOnAttachEventListener(myDiv, new EventListener() {
  @Override
  public void onEvent(Event event) {
    // ...
  }
}

当我做这样的事情时应该调用处理程序,

parent.appendChild(myDiv);

假设parent 是自己附加的,即它显示在当前窗口中。

【问题讨论】:

    标签: java gwt


    【解决方案1】:

    我发布第二个答案,因为现在我知道您无法更改将 DIV 添加到父级的方式。

    经过一番搜索,我找到了Mutation events。它们允许您收听DOMNodeInserted 事件:

    JS:

    myDiv.addEventListener("DOMNodeInserted", function (ev) {
        alert('added');
    }, false);
    

    在GWT中你需要使用JSNI方法:

    private native void addListener(Element elem) /*-{
        elem.addEventListener("DOMNodeInserted", function (ev) {
            $wnd.alert('added');
        }, false);
    }-*/;
    

    它有效,但是......它已被弃用。你应该改用MutationObserver

    不幸的是 MutationObserver 没有要观察的 NodeInserted 事件。我认为subtree 突变观察可以完成这项工作,但它对我不起作用。解决方案是观察父节点上的childList 突变:

    JS:

    // create an observer instance
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            alert(mutation.type);
        });    
    });
    
    // configuration of the observer:
    var config = {
        childList: true
    };
    
    // pass in the target node, as well as the observer options
    observer.observe(elem, config);
    

    同样,对于 GWT,您需要将其包装在 JSNI 方法中(您知道如何)。

    观察者回调中的mutation参数是一个MutationRecord对象。

    所以,如果你能得到父节点,请在其上使用 MutationObserver 并观察 childList 突变。如果没有,请尝试使用已弃用的 Mutation 事件。


    我知道这不是纯粹的 GWT 解决方案,但您可以使用 GWT 方法来处理事件或突变。你只需要像这样从 JSNI 调用 GWT 方法:

    [instance-expr.]@class-name::method-name(param-signature)(arguments)
    

    您可以在GWT documentation 中找到所有 JSNI 信息。

    【讨论】:

      【解决方案2】:

      GWT 中的所有Widgets 都已经实现了HasAttachHandlers 接口。如果您需要此功能,最好使用 Widget 而不是 Node。

      【讨论】:

      • 不幸的是,我受到一些框架限制,无法切换到小部件。
      • 接下来看看Widgets是如何实现这个接口的。如果我没记错的话,这并不是那么微不足道。
      【解决方案3】:

      您可以使用SimplePanelHTMLPanel,因为两者都使用DIV 作为其内容。

      在面板上你可以调用addAttachHandler 方法。

      如果您需要Element,您可以在面板上调用getElement() 方法。

      此方法仅在您将myDiv 附加为面板时才有效,因此不是

      parent.appendChild(myDiv);
      

      你应该这样做

      HTMLPanel.wrap(parent).add(myDiv);
      

      这是一个示例代码:

          Element parent = RootPanel.getBodyElement();
          SimplePanel myDiv = new SimplePanel();
      
          // use it as Panel
          myDiv.add(new Label("Hello!"));
      
          // or use it as an element
          myDiv.getElement().setInnerText("Hello 2!");
      
          myDiv.addAttachHandler(new Handler() {
              @Override
              public void onAttachOrDetach(AttachEvent event) {
                  Window.alert("Attached");
              }
          });
      
      //  parent.appendChild(myDiv.getElement());     // this will not fire the AttachEvent
          HTMLPanel.wrap(parent).add(myDiv);          // this will fire the AttachEvent
      

      【讨论】:

      • 不幸的是,我无法更改父级添加 myDiv 的方式。如果可以的话,我会在以任何方式向父级添加元素后立即“手动”处理。
      【解决方案4】:

      还有“轮询”替代方案,它可能不是很有效但更容易,请参阅https://stackoverflow.com/a/850995/938899

      【讨论】:

        猜你喜欢
        • 2015-01-23
        • 1970-01-01
        • 1970-01-01
        • 2016-04-26
        • 1970-01-01
        • 2021-03-17
        • 1970-01-01
        • 2022-01-17
        • 2017-04-16
        相关资源
        最近更新 更多