• 关于ZK框架的onScroll事件的问题


    由于我现在所在的公司用到的zk框架,遇到了一个需求frozen on top。 简单来说就是滚动超过范围后,希望有一块东西停留在滚动窗口的顶部。

    一.zk框架

    1. 查看了zk的8.x版本,发现组件的支持的事件(Event)最大的父类如下:

    * <p>Events:<br/>
     *  onClick, onDoubleClick, onRightClick, onDrop,
     *  onMouseOver, onMouseOut, onOK, onCacnel, onCtrlKey and onSwipe.<br/>
     *
    abstract public class HtmlBasedComponent extends AbstractComponent {
    ...
        static {
            addClientEvent(HtmlBasedComponent.class, Events.ON_CLICK, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_DOUBLE_CLICK, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_RIGHT_CLICK, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_OK, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_CANCEL, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_CTRL_KEY, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_DROP, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_MOUSE_OVER, 0); //not to use CE_DUPLICATE_IGNORE since there is an order issue
            addClientEvent(HtmlBasedComponent.class, Events.ON_MOUSE_OUT, 0);
            addClientEvent(HtmlBasedComponent.class, Events.ON_SWIPE, CE_DUPLICATE_IGNORE);
            addClientEvent(HtmlBasedComponent.class, Events.ON_AFTER_SIZE, CE_DUPLICATE_IGNORE);
        }
    ...
    }

    发现最大的组件所支持的事件并没有我们想要的onScroll事件。然后查一下你想要滚动的目标组件,比如说div component:

    div没有属于自己的事件注册。所以div所支持的事件都是父类的所注册的事件。

    如果说我们想要在div监听到滚动事件呢?

    二.创建属于自己系统的component

    ZK框架的扩展性非常强。zk允许用户定义属于自己的组件,所以在这次解决问题的时候我创建了自己的组件cbxDiv。

    我们需要做的有以下几点:

    1. 配置lang-addon.xml : 这是zk的配置文件,通常我们把所需要自己的组件信息都定义到这个配置文件,这样zk就会自动识别。
    <?xml version="1.0" encoding="UTF-8"?>
    <language-addon>
      <addon-name>cul</addon-name>
      <depends>zul,ckez</depends>
      <language-name>xul/html</language-name>
    ....
      <component>
        <component-name>cbxdiv</component-name>
        <component-class>com.core.cbx.ui.zk.cul.CbxDiv</component-class>
        <widget-class>cul.wgt.CbxDiv</widget-class>
        <extends>div</extends>
      </component>
    </language-addon>

    这里的component-class就是你组件class的具体位置,widget-class是自己定义的js文件的所在位置。extend当然就是父类。

    2.配置zk.wpd:这个是配置你组件的名字,以至于zk可以找到对应关系。

    <?xml version="1.0" encoding="UTF-8"?>
    
    
    <package name="cul.wgt" language="xul/html" depends="zul.wgt">
        <widget name="CbxDiv"/>
    </package>

    3.创建对应的component class

    public class CbxDiv extends Div {
    
        static {
            addClientEvent(CbxDiv.class, Events.ON_SCROLL, CE_IMPORTANT);
            addClientEvent(CbxDiv.class, Events.ON_SCROLLING, CE_IMPORTANT);
        }
    
        public CbxDiv() {
            super();
        }
    
        /*
         * (non-Javadoc)
         * @see org.zkoss.zk.ui.AbstractComponent#service(org.zkoss.zk.ui.event.Event, org.zkoss.zk.ui.ext.Scope)
         */
        @Override
        public void service(final AuRequest request, final boolean everError) {
            final String cmd = request.getCommand();
            if (Events.ON_SCROLL.equals(cmd)) {
                final ScrollEvent evt = ScrollEventExt.getScrollEventExt(request);
                Events.postEvent(evt);
            } else if (Events.ON_SCROLLING.equals(cmd)) {
                final ScrollEvent evt = ScrollEvent.getScrollEvent(request);
                Events.postEvent(evt);
            } else {
                super.service(request, everError);
            }
        }
    }
    addClientEvent()这个方法是注册你自己想要的事件的。重写service是为了具体到的事件对应的处理类。并且数据的绑定。
    注意:这个class创建的位置要跟lang-addon.xml配置的位置对应

    4.创建自己的js
    cul.wgt.CbxDiv = zk.$extends(zul.wgt.Div, {
    
        bind_: function() {
            this.$supers(cul.wgt.CbxDiv, 'bind_', arguments);
            this.domListen_(this.$n(), "onScroll", 'doScroll_');
        },
    
        unbind_: function() {
            this.domUnlisten_(this.$n(), "onScroll", 'doScroll_');
            this.$supers(cul.wgt.CbxDiv, 'unbind_', arguments);
        },
    
        doScroll_: function() {
            this.fire('onScroll',{'x':this.$n().scrollLeft,'y':this.$n().scrollTop},{toServer:true});
        }
    
    });

    主要的方法是对我们的component绑定一个事件,然后触发这个事件的时候发送数据到后台。数据是以map的形式传送。

    到这里基本上可以进行测试了。测试步骤就是创建一个cbxDiv,然后里面塞些东西。。在我们后台就可以动态的去加这个监听

    test1Div.addEventListener(Events.ON_SCROLL, new EventListener<ScrollEventExt>() {
      @Override
      public void onEvent(final ScrollEventExt event) throws Exception {
        system.out.print("scroll event have been fired!");
      }
    }
     
  • 相关阅读:
    CFgym102394I
    Infinite Fraction Path (后缀数组)
    2016ACM/ICPC亚洲区沈阳站-重现赛
    2sat学习笔记
    bzoj4176
    bzoj3309
    6C
    3U
    3T
    3R
  • 原文地址:https://www.cnblogs.com/dato/p/8805765.html
Copyright © 2020-2023  润新知