ZK框架中onScroll/onScrolling事件使用及Grid组件事件注册问询
解决ZK Grid组件滚动事件监听问题
你碰到的这个问题其实挺常见的——ZK原生Grid组件确实没有内置onScrolling或onScroll这类滚动事件,从HtmlBasedComponent的官方事件列表也能看出来,它只覆盖了点击、鼠标交互这类基础事件:
Events:
* onClick, onDoubleClick, onRightClick, onDrop, * onMouseOver, onMouseOut, onOK, onCancel, onCtrlKey and onSwipe.
下面给你两种可行的解决方案,分别适配快速实现和长期复用的场景:
方案一:客户端绑定+服务端监听(快速搞定)
不用改组件源码,直接利用ZK的客户端API把浏览器的滚动事件转成服务端能接收的事件,步骤很简单:
- 在Java代码里给Grid绑定客户端滚动监听:
// 给Grid的滚动容器绑定scroll事件,触发自定义服务端事件onGridScroll itemCustGrid.setWidgetListener("onScroll", "zk.Widget.$(this).fire('onGridScroll', {scrollTop: this.$n('body').scrollTop}, {toServer:true});");
- 服务端注册对应的事件监听器处理逻辑:
itemCustGrid.addEventListener("onGridScroll", new EventListener<Event>() { @Override public void onEvent(Event event) throws Exception { // 从事件数据里拿滚动位置 Map<String, Object> scrollData = (Map<String, Object>) event.getData(); int scrollTop = (Integer) scrollData.get("scrollTop"); // 这里写你的滚动处理逻辑 System.out.println("Grid当前滚动位置:" + scrollTop); } });
这个方法的核心是用WidgetListener把浏览器原生的scroll事件包装成ZK服务端能识别的自定义事件,几分钟就能搞定,适合临时需求。
方案二:自定义扩展Grid组件(长期复用)
如果你的项目里多个地方都需要带滚动事件的Grid,那不如直接扩展原生Grid,把滚动事件做成内置能力:
- 写一个自定义Grid类,继承原生
Grid,注册自定义事件:
public class ScrollableGrid extends Grid { static { // 告诉ZK框架我们要新增一个onScroll事件 addClientEvent(ScrollableGrid.class, "onScroll", 0); } @Override protected void renderProperties(ContentRenderer renderer) throws IOException { super.renderProperties(renderer); // 自动绑定客户端滚动事件到服务端的onScroll render(renderer, "onScroll", "zk.Widget.$(this).fire('onScroll', {scrollTop: this.$n('body').scrollTop}, {toServer:true});"); } }
- 在ZUL里使用这个自定义组件(或者Java代码实例化):
<!-- 记得先声明自定义组件的命名空间 --> <custom:scrollableGrid id="itemCustGrid" width="100%" height="400px"> <!-- 你的Grid列和内容 --> </custom:scrollableGrid>
- 服务端直接监听
onScroll事件就行:
itemCustGrid.addEventListener("onScroll", new EventListener<Event>() { @Override public void onEvent(Event event) throws Exception { int scrollTop = (Integer) ((Map<String, Object>) event.getData()).get("scrollTop"); // 处理滚动逻辑 } });
这样扩展后,ScrollableGrid就和原生组件一样好用,哪里需要直接用就行。
小提醒
滚动事件触发频率很高,如果服务端处理的逻辑比较重,建议在客户端加个防抖(比如延迟50ms再触发事件),避免给服务端发太多请求。另外要注意,ZK Grid的滚动区域是内部的body节点(this.$n('body')),别搞错监听对象哦。
内容的提问来源于stack exchange,提问作者zeng dato
相关产品推荐
相关产品推荐

