Why doesn't GWT let us add key event handlers on document element?
I know there's FocusPanel
on which I can attach such handlers, but in my experience this component does not behave that well. So I'd like to avoid it as much as possible.
So I'm wondering why there's no way to attach key handlers on document too? According to quirksmode.org it works cross-browser, so this shouldn't be a concern.
I've also tried writing some JSNI code to do this myself, which works ok for most cases. However, if there's any other widget that listens for the same event as me on document, and that widget lets the event propagate, I can do pretty much nothing with the event that reached the document, because it's marked as dead and an exception will be thrown whenever I try to access data on that event.
Here's my code s开发者_如何学JAVAo far:
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);
}
}-*/;
}
How about the following?
RootPanel.get().addDomHandler(handler, KeyDownEvent.getType());
It adds them on the document's body, but that's not much different.
精彩评论