【问题标题】:Why doesn't GWT let us add key event handlers on document element?为什么 GWT 不允许我们在文档元素上添加关键事件处理程序?
【发布时间】:2011-10-12 09:18:44
【问题描述】:

我知道有FocusPanel 可以附加这样的处理程序,但根据我的经验,这个组件的表现并不好。所以我想尽可能避免它。

所以我想知道为什么也没有办法在文档上附加密钥处理程序?根据quirksmode.org 的说法,它可以跨浏览器工作,所以这不应该是一个问题。

我也尝试自己编写一些 JSNI 代码来执行此操作,这在大多数情况下都可以正常工作。但是,如果有任何其他小部件在文档上侦听与我相同的事件,并且该小部件允许事件传播,那么我对到达文档的事件几乎无能为力,因为它被标记为死,并且将出现异常每当我尝试访问该事件的数据时抛出。

到目前为止,这是我的代码:

public class RichDocument implements HasKeyPressHandlers, HasKeyDownHandlers,
    HasKeyUpHandlers, HasClickHandlers {

  private static final RichDocument instance = new RichDocument();

  public static RichDocument get() {
    return instance;
  }

  private final EventBus eventBus = new SimpleEventBus();

  private RichDocument() {
    startListening();
  }

  @Override
  public HandlerRegistration addClickHandler(ClickHandler handler) {
    return eventBus.addHandler(ClickEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
    return eventBus.addHandler(KeyDownEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
    return eventBus.addHandler(KeyPressEvent.getType(), handler);
  }

  @Override
  public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
    return eventBus.addHandler(KeyUpEvent.getType(), handler);
  }

  @Override
  public void fireEvent(GwtEvent<?> event) {
    eventBus.fireEvent(event);
  }

  private native void startListening()/*-{
    var self = this;

    var fire = function (event) {
      event = event || $wnd.event;
      @com.google.gwt.event.dom.client.DomEvent::fireNativeEvent(Lcom/google/gwt/dom/client/NativeEvent;Lcom/google/gwt/event/shared/HasHandlers;)(event, self);
    };

    if ($wnd.document.addEventListener) {
      $wnd.document.addEventListener("click", fire, false);
      $wnd.document.addEventListener("keydown", fire, false);
      $wnd.document.addEventListener("keypress", fire, false);
      $wnd.document.addEventListener("keyup", fire, false);
    } else {
      $wnd.document.attachEvent("onclick", fire);
      $wnd.document.attachEvent("onkeydown", fire);
      $wnd.document.attachEvent("onkeypress", fire);
      $wnd.document.attachEvent("onkeyup", fire);
    }
  }-*/;
}

【问题讨论】:

  • 您是否有特定的理由要添加到文档而不是使用Event.addNativePreviewHandler()
  • @HilbrandBouwkamp 我不知道这种方法,谢谢!我试试看。
  • 请注意,addNativePreviewHandler 作用于捕获阶段(在 IE 中模拟),而“附加到文档”将处于冒泡阶段。这可以有所作为。取决于你的需要。
  • @HilbrandBouwkamp, @ThomasBroyer addNativePreviewHandler 似乎有效,但我如何将该事件转换为正确的KeyUpEvent

标签: events gwt keyboard-events


【解决方案1】:

下面的呢?

RootPanel.get().addDomHandler(handler, KeyDownEvent.getType());

它将它们添加到文档的正文中,但这并没有太大的不同。

【讨论】:

  • 不同的是,文档总是占据整个视口,而body元素则不一定。例如,如果 body 有 CSS width: 200px; height: 200px; margin: 200px auto;,则 body 区域非常小。只是一个例子。
  • 这就是为什么我说“差别不大”而不是“相同”。不过,让body 占据整个视口相对容易。我相信有某种骇客可以使注册文档成为可能,甚至无需接触 JSNI(使用 Document.get().&lt;Element&gt;cast()DOM.setEventListenerDOM.sinkEvents)。
  • 是的,它似乎可以工作,但我如何将该事件转换为 KeyUpEvent 或类似事件。
  • DomEvent.fireNativeEvent,您可以在其中传递任何HasKeyUpHandlers,或您自己的HasHandlers 实现,或者只需在您之前注册HasKeyUpHandlers 的地方使用HandlerManager(如在小部件中)。
猜你喜欢
  • 2019-10-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2021-05-16
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多