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 事件系统分派的非冒泡事件有特殊处理。 并且支持非冒泡事件的类型列表太短,仅限于focusblurloaderror事件。 有关详细信息,请参阅 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 项目中创建问题的主题。