zoukankan      html  css  js  c++  java
  • javascript

      在javascript - 工作笔记 (事件绑定二)篇中,我将事件的方法做了简单的包装,

     JavaScript Code 
    1
    2
    3
    4
    5
     
    yx.bind(item, "click"function (e) {
            
    //console.log("Div Click 1 !");
            alert("Div Click 1 !");
            e.stopPropagation();
        });

      但是这样用起来有些不顺手,添加方法还要加个标签元素对象,能不能去掉第一个参数呢,答案是肯定的。

    我们只需要将DOM元素对象转换成Yx对象,就可以了。但是要如何将dom变成Yx对象呢,如下:

     JavaScript Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    var Yx = function (ele) {//dom元素对象
        
    var self = this;
        
    if (
        (ele 
    instanceof Array) ||
        (NodeList || (ele 
    instanceof NodeList))) {
            
    for (var i = 0; i < ele.length; i++) {
                self[i] = ele[i];
            }
            self.length = ele.length;
        } 
    else {
            self[
    0] = ele;
            self.length = 
    1;
        }
        
    return self;
    }

      我们将dom元素对象挂在Yx对象的下面,像数组一样,使用下标获取,设置值,同时还保留了DOM节点自带的方法,属性。这时,我们使用的时候如下:

     JavaScript Code 
    1
    2
    3
     
    var item = document.getElementById("test");//获取dom对象
    var yxItem = new Yx(item);//新建Yx对象
    yxItem.bind( "click"function (e) { ... });//绑定事件

      但,这样写也有点不爽,每次还要new一下,能省掉new吗,当然可以。

     JavaScript Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Yx.prototype.init = function(ele){
        
    var self = this;
        
    if(
        (ele 
    instanceof Array) ||
        (NodeList || (ele 
    instanceof NodeList))){
            
    for(var i=0;i<ele.length;i++){
                self[i] = ele[i];
            }
            self.length = ele.length;
        }
    else{
            self[
    0] = ele;
            self.length = 
    1;
        }
        
    return self;
    }

      我们新建一个方法为init用来新建Yx对象使用,同时,我们在构造方法中,这样写:

     JavaScript Code 
    1
    2
    3
    4
    5
    6
    7
    8
     
    var Yx = function(ele){

        Yx.fn = Yx.
    prototype;//将Yx原型链赋值给Yx.fn
        Yx.fn.init.prototype = Yx.fn;//实际是将Yx的原型链赋值给Yx.fn.init,这样Yx.fn.init就具有与Yx一样的原型链,
        
        
    return new Yx.fn.init(ele);//在这里实例化的是Yx.fn对象,但是它具有有Yx一样的原型链,
        //new 出来的对象与Yx对象是相同的
    }
    //这种方法因为在使用的时候去掉了new,被称为无new的构造方法,在源码中,我介绍了两种无new方法,写法不同,其实原理一样。

    这时候我们使用方法如下:

     JavaScript Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var item = document.getElementById("test");  
    var yxItem = yx(item);//直接调用yx方法,该方法中new Yx.fn对象
    yxItem.bind("click",function(e){
        console.log(
    "Div Click 1 !");
        e.stopPropagation();
    });


    window.$ = window.yx = Yx;//当然得有这么一句话才能直接使用yx(...)方法了,

    完整代码如下:

     JavaScript Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    (function (window) {

        
    var Yx = function (ele) {

            
    //第一种无new实现方法
            var a = Yx.prototype//将Yx.prototype存入a变量中,这样a变量中就含有了init这个方法,应该叫做对象
            //在javascript中任何事物都是对象,函数也是对象,xxx()是执行函数,new xxx()则是新建对象了,
            a.init.prototype = a; //将a(即:Yx.prototype原形链赋值给a.init对象的原形链,使这两个对象具有相同的方法,属性)
            return new a.init(ele); //新建一个a.init对象,该对象与new Yx(else)的对象具有相同的方法,属性

            
    //第二种无new实现方法

            
    //Yx.fn = Yx.prototype;
            //Yx.fn.init.prototype = Yx.fn;
            //return new Yx.fn.init(ele);
        }
        Yx.evGuid = 
    0;
        window.NodeList = 
    function () { } || window.NodeList;//IE下午NodeList对象
        //初始化
        Yx.prototype.init = function (ele) {
            
    var self = this;
            
    if (
        (ele 
    instanceof Array) ||
        (NodeList && (ele 
    instanceof NodeList))) {
                
    for (var i = 0; i < ele.length; i++) {
                    self[i] = ele[i];
                }
                self.length = ele.length;
            } 
    else {
                self[
    0] = ele;
                self.length = 
    1;
            }
            
    return self;
        }
        Yx.
    prototype.bind = function (evName, evFunc) {
            
    var self = this;
            
    for (var i = 0; i < self.length; i++) {
                self.bindEv(self[i], evName, evFunc);
            }
        }
        Yx.
    prototype.unbind = function (evName, evFunc) {
            
    var self = this;
            
    for (var i = 0; i < self.length; i++) {
                self.unbindEv(self[i], evName, evFunc);
            }
        }
        
    //绑定事件
        Yx.prototype.bindEv = function (ele, evName, evFunc) {
            
    if (!evFunc.$$guid) evFunc.$$guid = Yx.evGuid++; //为新添加的事件添加标识
            if (!ele.events) ele.events = {}; //为元素添加事件集合
            evName = evName;
            
    if (!ele.events[evName]) {
                ele.events[evName] = {};
            }
            
    if (ele.events[evName][evFunc.$$guid] == undefined)
                ele.events[evName][evFunc.$$guid] = {};
            ele.events[evName][evFunc.$$guid] = evFunc;
            ele[
    "on" + evName] = eventManager; //事件统一处理
        }
        
    //解绑事件
        Yx.prototype.unbindEv = function (ele, evName, evFunc) {
            
    if (ele.events && ele.events[evName]) {
                
    delete ele.events[evName][evFunc.$$guid];
            }
        }
        
    //事件管理
        function eventManager(e) {
            
    var self = this//当前对象
            var e = e || window.event; //event对象
            if (!e.stopPropagation) {//IE下的阻止默认行为,事件冒泡
                e.preventDefault = function () { this.returnValue = false; }
                e.stopPropagation = 
    function () { this.cancelBubble = true; }
            }
            
    var evFuncs = self.events[e.type]; //获取当前对象,指定的事件名称事件数组
            for (var key in evFuncs) {
                evFuncs[key](e, self);
            }
        }
        window.$ = window.yx = Yx;
    //将Yx方法给两个别名
    })(window);

    var test = document.getElementById("test");
    var testItem = yx(test);

    testItem.bind(
    "click"function (e) {
        
    //console.log("Div Click 1 !");
        alert("Div Click 1 !");
        e.stopPropagation();
    });

    var funcTest1 = function (e) {
        
    //console.log("Div Click 2 !");
        alert("Div Click 2 !");
    };

    testItem.bind(
    "click", funcTest1);

    var pArr = document.getElementsByTagName("p");
    var pArrItem = $(pArr);

    pArrItem.bind(
    "click"function (e, item) {
        
    //console.log(item.innerHTML);
        alert(item.innerHTML);
        e.preventDefault();
    });

    var link = document.getElementById("a_link");
    var linkItem = $(link);
    linkItem.bind(
    "click"function (e, item) {
        
    //console.log(item.innerHTML);
        alert(item.innerHTML);
        e.preventDefault();
    });

      第一种无new方法与第二种无new方法原理一样,只是第一种方法看的明白些,第二种看起来NB一些,哈哈!

      Demo请点这里

  • 相关阅读:
    PetaLinux 生成 Zynq 操作系统
    单片机、微控制器和微处理器有什么区别
    嵌入式基础概念系列(1) —— GPIO
    学中杂记
    Spring学习笔记
    jdbc一点小笔记
    JSP学习
    Servlet学习的一些笔记
    接触Struts2的ModelDriven<>接口
    android-dialog的位置
  • 原文地址:https://www.cnblogs.com/urols-jiang/p/3947991.html
Copyright © 2011-2022 走看看