I have a simple GWT setup for testing:
<g:HTMLPanel ui:field="container" width="500px" height="300px">
<g:Label ui:field="inner" text="hello"></g:Label>
</g:HTMLPanel>
With handlers added:
container.addDomHandler(new ClickHandler()
{
@Override
public void onClick(ClickEvent event)
{
Window.alert("click on container");
}
}, ClickEvent.getType());
inner.addDomHandler(new ClickHandler()
{
@Override
public void onClick(ClickEvent event)
{
Window.alert("click on inner");
}
}, ClickEvent.getType());
Each of these addHandler calls, as we know from the sources,
DOM.sinkEvents(Element elem, int eventBits)
inside, and the latter, according to docs, "Sets the current set of events sunk by a given element. These events will be fired to the nearest {@link EventListener} specified on any of the element's parents."
But in fact, if you click on inner div the click will be fired to its parent div in any of the 3 ways:
if I have not set any ClickHandlers on child
if I have set handlers on child
if I have set the handlers, but cleared the sinking of ClickEvent with
DOM.sinkEvents(inner.getElement(), DOM.getEventsSunk(getElement()) & ~Event.getTypeInt(ClickEvent.getType().getName()));
Why this happens and what is the true role of sinking the events? Why adding a Handler is related to sinking events, i.e. to firing the same event to parent of the given element? Is it possible to prevent all handlers, added to the given widget from calling without removing them explicitely? I.e. is there a way to stop processing all events on some widget?
First, sinkEvent
is about adding the native event handler on the element, as explained in the GWT wiki.
What you're seeing is event bubbling, which is how events work in browsers: there are 2 phases when dispatching an event: the capture phase (not implemented in old IEs) allows any ancestor element to catch the event before it reaches its target, then in the bubbling phase the event bubbles up the DOM hierarchy. So if you listen for clicks on the HTMLPanel
, you'll also receive the bubbling click events from the Label
.
You can prevent that by listening to the event at the Label
level and calling stopPropagation()
so it doesn't bubble up to the HTMLPanel
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With