Events 为什么';GWT让我们在文档元素上添加关键事件处理程序?

Events 为什么';GWT让我们在文档元素上添加关键事件处理程序?,events,gwt,keyboard-events,Events,Gwt,Keyboard Events,我知道我可以在FocusPanel上附加这样的处理程序,但根据我的经验,这个组件的性能并不好。所以我想尽量避免 所以我想知道为什么没有办法在文档上附加键处理程序呢?根据它的工作原理,跨浏览器,所以这不应该是一个问题 我也尝试过自己编写一些JSNI代码来实现这一点,这在大多数情况下都是可行的。但是,如果有任何其他小部件侦听文档中与我相同的事件,并且该小部件允许事件传播,那么我几乎无法处理到达文档的事件,因为它被标记为死事件,并且每当我尝试访问该事件的数据时,都会引发异常 以下是我目前的代码: pu

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

所以我想知道为什么没有办法在文档上附加键处理程序呢?根据它的工作原理,跨浏览器,所以这不应该是一个问题

我也尝试过自己编写一些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);
    }
  }-*/;
}
public类RichDocument实现HasKeyPressHandlers、HasKeyDownHandlers、,
HasKeyUpHandlers,HasClickHandlers{
私有静态最终RichDocument实例=新的RichDocument();
公共静态文档get(){
返回实例;
}
private final EventBus EventBus=新的SimpleEventBus();
私人文件(){
惊人的倾听();
}
@凌驾
公共句柄注册addClickHandler(ClickHandler处理程序){
返回eventBus.addHandler(ClickEvent.getType(),handler);
}
@凌驾
公共句柄注册addKeyDownHandler(KeyDownHandler处理程序){
返回eventBus.addHandler(KeyDownEvent.getType(),handler);
}
@凌驾
公共句柄注册addKeyPressHandler(KeyPressHandler处理程序){
返回eventBus.addHandler(KeyPressEvent.getType(),handler);
}
@凌驾
公共句柄注册addKeyUpHandler(KeyUpHandler处理程序){
返回eventBus.addHandler(KeyUpEvent.getType(),handler);
}
@凌驾
公共无效火灾事件(GwtEvent事件){
eventBus.fireEvent(事件);
}
私有本机void侦听()/*-{
var self=这个;
var火灾=功能(事件){
事件=事件| |$wnd.event;
@fireNativeEvent(Lcom/google/gwt/dom/client/NativeEvent;Lcom/google/gwt/event/shared/HasHandlers;)(事件,自我);
};
if($wnd.document.addEventListener){
$wnd.document.addEventListener(“单击”,发射,假);
$wnd.document.addEventListener(“键控”,火灾,假);
$wnd.document.addEventListener(“按键”,火,假);
$wnd.document.addEventListener(“keyup”,fire,false);
}否则{
$wnd.文件附件(“onclick”,火灾);
$wnd.文件附件(“onkeydown”,火灾);
$wnd.文件附件(“onkeypress”,火灾);
$wnd.文件附件(“onkeyup”,火灾);
}
}-*/;
}

以下内容如何

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

它将它们添加到文档的主体上,但差别不大。

文档总是占据整个视口,而主体元素不一定占据整个视口。例如,如果主体具有CSS
width:200px;高度:200px;利润率:200px自动,身体的面积真的很小。举个例子,这就是为什么我说“没什么不同”和“不一样”。不过,让
主体占据整个视口相对容易。我相信有某种黑客可以在文档中注册,而不必触碰JSNI(使用
document.get().cast()
DOM.setEventListener
DOM.sinkEvents
)。是的,它似乎可以工作,但我如何将该事件转换为KeyUpEvent,或类似的。
DomEvent.fireNativeEvent
,您可以在其中传递任何
HasKeyUpHandlers
,或您自己的
hashHandlers
实现,或者只需使用
HandlerManager
,您以前在其中注册了
HasKeyUpHandlers
(如在小部件中)。您是否有特定的原因要添加到文档而不是使用
事件。addNativePreviewHandler()
?@HilbrandBouwkamp我不知道此方法,谢谢!请注意,
addNativePreviewHandler
在捕获阶段起作用(在IE中模拟),而“附加到文档”则在冒泡阶段。这可能会有所不同。取决于您的需要。@HilbrandBouwkamp,@ThomasBroyer addNativePreviewHandler似乎可以工作,但如何将该事件转换为适当的
KeyUpEvent