zoukankan      html  css  js  c++  java
  • QWrap简介之:EventW Event包装

    事件在dom操作中,也有着重要的意义。不过,对于项目程序员同学,只需知道怎么用就可以了。如果在看本文之前,还没有理解清楚标准的dom event,那么请忽略本文,免得产生更多的纠结。
    事件对象与节点对象一样,无法通过渲染原生dom的Event的原型来达到扩展与兼容的效果,所以,也采用Wrap模型来解决这个问题。
    EventW就是针对Event的包装。它的核是原生的event。
    前面介绍NodeW是按进化的思路由浅入深的介绍,反个方向,从最终用法来反观EventW的实现。

    event在事件监控中会用到。
    为元素添加事件,通常的用法应该是这样的:
    //<div class="mydiv">content1<a href="http://www.baidu.com">baidu</a></div>
    var handler=function(e){
    alert(e.type);
    //事件类型
    alert(this.innerHTML); //this是被监控的节点对象
    alert(e.target.innerHTML); //this.target是触发事件的对象
    alert(e.preventDefault()); //阻止事件默认操作
    };
    W(
    'div.aaa').on('click', handler);

    熟悉浏览器的同学可能知道,对于标准浏览器,上面的用法很自然;但是对于某些版本的IE,如果on是直接调用原生的attachEvent,则上面的代码会不是预期效果,
    其中的e.target会是空,而this会是window,等等,很多地方不符合预期。
    但是,事实上我们可以这么用。原因是什么?
    因为,NodeW.prototype里的on,做了一个偷梁换柱的小动作:它把handler函数进行了一个变换,之后将变换的结果当作新的监控函数传给dom的相关方法。
    看一下on静态实现的简单示意代码:
    EventTargetH.on = function(element, sEvent, handler) {
    var _listener = listener(element, sEvent, handler);
    EventTargetH.addEventListener(element, name, _listener);
    };
    function listener(element, name, handler) {
    return function(e) {
    return fireHandler(element, e, handler, name);
    };
    }

    这个偷梁换柱的小动作,让我们把handler的this与arguments、甚至包括触发时机的主动权从浏览器那里抢过来,放到fireHandler里去了。
    有了这个主动权,我们让handler里的this,指向被监控的节点;让arguments[0]变成了一个确定存在的e,不过,这个e不是原生的“e||window.event”,而一个新的东西:EventW的实例,相当于:e=new EventW(e||window.event)。

    那我们看下EventW是个什么东东吧:
    /**
    * @class EventW Event Wrap,event对象包装器
    * @namespace QW
    */
    (
    function() {
    var mix = QW.ObjectH.mix,
    methodize
    = QW.HelperH.methodize;

    QW.EventW
    = function(e) {
    this.core = e || window.event; //core 原生Event实例
    this.target = this.getTarget(); //target 事件触发的元素
    this.relatedTarget = this.getRelatedTarget(); //relatedTarget事件的相关元素.
    this.pageX = this.getPageX();
    this.pageY = this.getPageY();
    this.detail = this.getDetail();
    this.keyCode = this.getKeyCode();
    this.ctrlKey = this.getCtrlKey();
    this.shiftKey = this.getShiftKey();
    this.altKey = this.getAltKey();
    this.button = this.core.button;
    this.clientX = this.core.clientX;
    this.clientY = this.core.clientY;
    this.type = this.core.type;
    };

    mix(QW.EventW.prototype, methodize(QW.EventH,
    'core'));
    }());


    看起来很简单,其实就是一个core为原生event的对象,不过在构造时,同时仿照dom event标准给他赋了一套属性。
    可能有的同学会问:这里的this.getTarget、this.getRelatedTarget等方法是哪里来的?
    答:是这一句话带来的:“mix(QW.EventW.prototype, methodize(QW.EventH, 'core'));”
    这一句话的意思是:将EventH里的所有静态方法,转变成EventW的原型方法。除了在构造器里用到的,还包括preventDefault、cancelBubble等方法,所以,在实际应用中,可以像原生的event一样这样调用:e.preventDefault()来阻止默认事件。
    明白了这些思路,代码看起来很简单吧。

    可能会有同学有疑惑,频繁创建EventW,不会有效率问题么,尤其是在mousemove时?
    虽说是频繁创建并且赋属性,不过都是简单调用与赋值,就算鼠标频率调到100hz,这个创建时间也是小到可以忽略不计的。----具体没测过相关数值,但在目前所有的应用项目中,没发现有问题。

    QWrap中,与evnet相关的类与命名空间共有三个:
    EventH:http://dev.qwrap.com/resource/js/dom/event.h.js
    EventTargetH:http://dev.qwrap.com/resource/js/dom/eventtarget.h.js
    EventW:http://dev.qwrap.com/resource/js/dom/event.w.js
    EventH与EventTargetH都是满足“纯洁、静态、针对性”特征的Helper,理解起来相对容易点。
    在组件开发中,为了无依赖化,可能会直接用到上面两个Helper,
    而在使用QWrap的项目中,它们几乎不会用到,因为EventH的功能,已传递给EventW了;而EventTargetH的功能,也会传递给NodeW。
    这种功能的传递与转化,就是QWrap所提的retouch机制,且听下回分解。

    附:QWrap网址:http://www.qwrap.com
  • 相关阅读:
    iview表格render多元素封装
    iview表单语法
    vue实例,extend methods——实例属性 vue和jQuery.js一起使用
    vue.js基础__ extend 扩展选项
    vue.js基础__ mixins 选项
    vue.js基础__ watch 选项
    vue.js基础__ methods 选项
    vue.js基础__ computed 选项
    vue.js基础__ propsData 选项
    vue-cli, webpack + vue 目录结构解读
  • 原文地址:https://www.cnblogs.com/jkisjk/p/qwrap_wrap_EventW.html
Copyright © 2011-2022 走看看