我有一个简单的GWT设置用于测试:
<g:HTMLPanel ui:field="container" width="500px" height="300px">
<g:Label ui:field="inner" text="hello"></g:Label>
</g:HTMLPanel>
Run Code Online (Sandbox Code Playgroud)
添加处理程序:
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());
Run Code Online (Sandbox Code Playgroud)
正如我们从消息来源所知,这些addHandler调用中的每一个都是
DOM.sinkEvents(Element elem,int eventBits)
根据文档,内部和后者"设置由给定元素沉没的当前事件集.这些事件将被触发到在任何元素的父元素上指定的最近的{@link EventListener}."
但事实上,如果你点击内部div,点击将以3种方式中的任何一种方式触发到其父div:
如果我没有在child上设置任何ClickHandlers
如果我在孩子身上设置了处理程序
如果我已设置处理程序,但清除了ClickEvent的下沉
DOM.sinkEvents(inner.getElement(),DOM.getEventsSunk(getElement())&~Event.getTypeInt(ClickEvent.getType().getName()));
为什么会发生这种情况以及下沉事件的真正作用是什么?为什么添加Handler与下沉事件有关,即将同一事件发送给给定元素的父元素?是否可以阻止添加到给定小部件中的所有处理程序进行调用而不会明确地删除它们?即有没有办法停止处理某些小部件上的所有事件?
首先,sinkEvent是关于在元素上添加本机事件处理程序,如GWT wiki中所述.
您所看到的是事件冒泡,这是事件在浏览器中的工作方式:调度事件时有两个阶段:捕获阶段(未在旧IE中实现)允许任何祖先元素在事件到达其目标之前捕获事件,然后在冒泡阶段,事件冒出 DOM层次结构.因此,如果您收听点击次数HTMLPanel,您还会收到来自的点击事件Label.
您可以通过在Label级别上监听事件并进行呼叫来防止这种情况发生,stopPropagation()因此它不会冒泡到HTMLPanel.