首页 > 代码库 > javascript - 工作笔记 (事件四)
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请点这里
javascript - 工作笔记 (事件四)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。