GXT - 无法访问文本区域上的 onscroll 事件处理程序
GXT - Can't reach onscroll event handler on text area
我正在尝试在文本区域 (gxt) 上设置一个处理程序来了解用户何时到达文本区域的顶部。
TextArea logTextArea = new TextArea();
logTextArea.setReadOnly(true);
logTextArea.addDomHandler(new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
InputElement textAreaElement = logTextArea.getCell().getInputElement(logTextArea.getElement());
int scrollTop = textAreaElement.getScrollTop();
}
}, ScrollEvent.getType());
VerticalLayoutContainer dataContainer = new VerticalLayoutContainer();
HorizontalLayoutContainer secondRow = new HorizontalLayoutContainer();
secondRow.add(logTextArea, new HorizontalLayoutData(1, 1, new Margins(5, 10, 5, 10)));
dataContainer.add(secondRow, new VerticalLayoutData(1, 0.5));
add(dataContainer);//this class extends ContentPanel
此处理程序永远不会在滚动时调用,但我也尝试了很多其他事件,例如鼠标悬停、mousewhell、mouseclick ...,所有这些事件都有效。有人可以提供任何想法吗?
据我所知,如果事件的目标和小部件不是相同的元素,则滚动事件将无法在开箱即用的基于单元格的小部件中工作。
而GXT的TextArea就是一个具有这种DOM结构的widget。
那是因为滚动事件是一个 "non bubbling" 事件。
AFAIK,使用单元格的 GWT 小部件,对通过 GWT 事件系统分派的非冒泡事件有特殊处理。
并且支持非冒泡事件的类型列表太短,仅限于focus
、blur
、load
和error
事件。
有关详细信息,请参阅 CellBasedWidgetImplStandard
class。
我可能建议的第一个解决方案 是为文本区域显式分配 onscroll 处理程序。
例如:
Event.sinkEvents(textAreaElement, Event.getEventsSunk(textAreaElement) | Event.ONSCROLL);
此处 textAreaElement
- 是文本区域 DOM 元素。
但是每次单元格重新呈现其内容时都应该这样做(例如,当为 TextArea 小部件调用 setValue 方法时)。
其他解决方案 有点老套并使用私有 api 实现,但只能应用于基于单元格的小部件一次。您可以执行与 CellBasedWidgetImplStandard.sinkEvent(Widget, String)
中相同的操作,例如:
WidgetHelper.sinkEvent(logTextArea.getElement(), BrowserEvents.SCROLL);
其中 WidgetHelper
可能如下所示:
public class WidgetHelper {
public static void sincEvent(Element element, String typeName){
element.setAttribute("__gwtCellBasedWidgetImplDispatching" + typeName, "true");
sinkEvent0(element, typeName);
}
private static native void sinkEvent0(Element element, String typeName) /*-{
element.addEventListener(typeName,
@com.google.gwt.user.cellview.client.CellBasedWidgetImplStandard::dispatchNonBubblingEvent, true);
}-*/;
}
可能,这是在 GWT 项目中创建问题的主题。
我正在尝试在文本区域 (gxt) 上设置一个处理程序来了解用户何时到达文本区域的顶部。
TextArea logTextArea = new TextArea();
logTextArea.setReadOnly(true);
logTextArea.addDomHandler(new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
InputElement textAreaElement = logTextArea.getCell().getInputElement(logTextArea.getElement());
int scrollTop = textAreaElement.getScrollTop();
}
}, ScrollEvent.getType());
VerticalLayoutContainer dataContainer = new VerticalLayoutContainer();
HorizontalLayoutContainer secondRow = new HorizontalLayoutContainer();
secondRow.add(logTextArea, new HorizontalLayoutData(1, 1, new Margins(5, 10, 5, 10)));
dataContainer.add(secondRow, new VerticalLayoutData(1, 0.5));
add(dataContainer);//this class extends ContentPanel
此处理程序永远不会在滚动时调用,但我也尝试了很多其他事件,例如鼠标悬停、mousewhell、mouseclick ...,所有这些事件都有效。有人可以提供任何想法吗?
据我所知,如果事件的目标和小部件不是相同的元素,则滚动事件将无法在开箱即用的基于单元格的小部件中工作。 而GXT的TextArea就是一个具有这种DOM结构的widget。
那是因为滚动事件是一个 "non bubbling" 事件。
AFAIK,使用单元格的 GWT 小部件,对通过 GWT 事件系统分派的非冒泡事件有特殊处理。
并且支持非冒泡事件的类型列表太短,仅限于focus
、blur
、load
和error
事件。
有关详细信息,请参阅 CellBasedWidgetImplStandard
class。
我可能建议的第一个解决方案 是为文本区域显式分配 onscroll 处理程序。 例如:
Event.sinkEvents(textAreaElement, Event.getEventsSunk(textAreaElement) | Event.ONSCROLL);
此处 textAreaElement
- 是文本区域 DOM 元素。
但是每次单元格重新呈现其内容时都应该这样做(例如,当为 TextArea 小部件调用 setValue 方法时)。
其他解决方案 有点老套并使用私有 api 实现,但只能应用于基于单元格的小部件一次。您可以执行与 CellBasedWidgetImplStandard.sinkEvent(Widget, String)
中相同的操作,例如:
WidgetHelper.sinkEvent(logTextArea.getElement(), BrowserEvents.SCROLL);
其中 WidgetHelper
可能如下所示:
public class WidgetHelper {
public static void sincEvent(Element element, String typeName){
element.setAttribute("__gwtCellBasedWidgetImplDispatching" + typeName, "true");
sinkEvent0(element, typeName);
}
private static native void sinkEvent0(Element element, String typeName) /*-{
element.addEventListener(typeName,
@com.google.gwt.user.cellview.client.CellBasedWidgetImplStandard::dispatchNonBubblingEvent, true);
}-*/;
}
可能,这是在 GWT 项目中创建问题的主题。