之前我们模拟过jQuery的自定义事件,数据是直接绑定在元素上面。但我们知道,那样容易引起内存泄露。我们看看jQuery是如何做到的。
其实,jQuery的事件是基于Data开发的,其核心的三个方法add(), remove()和trigger()都是和Data对象在打交道。让我们来剖析jQeury事件的核心:Data数据结构。
首先在jQuery源码中把其console出来。
1 jQuery.event = { 2 3 global: {}, 4 5 add: function( elem, types, handler, data, selector ) { 6 console.log(elemData) 7 }, 8 ...
1 var $clickTrigger = $("#clickTrigger"); 2 //var $doTrigger = $("#doTrigger"); 3 $clickTrigger.on("click", function(a){ 4 console.log(1) 5 }) 6 $clickTrigger.on("click", function(b){ 7 console.log(2) 8 }) 9 $clickTrigger.on("mouseover", function(c){ 10 console.log(3) 11 })
html代码
<input id="clickTrigger" type="button" value="click事件" />
这个时候我们可以看到的结构是:
1 var elemData = { 2 events: { 3 click:[//还有一个delegateCount属性 4 { 5 data: undefined,//传递的参数 6 guid: 1,//当前事件唯一标识,根据绑定顺序分配 7 handler: function(a){},//绑定的是普通函数 8 namespace: "",//命名空间 9 needsContext: undefined,//委托,伪类的写法 10 origType: "click",//原始的事件类型,如mouseenter 11 selector: undefined,//放的是委托元素 12 type: "click"//现在的事件类型,如mouseover 13 }, 14 { 15 data: undefined, 16 guid: 2, 17 handler: function(b){}, 18 namespace: "", 19 needsContext: undefined, 20 origType: "click", 21 selector: undefined, 22 type: "click" 23 } 24 ], 25 mouseover:[//还有一个delegateCount属性 26 { 27 data: undefined, 28 grid: 3, 29 handler: function(c){}, 30 namespace: "", 31 needsContext: undefined, 32 origiType: "mouseover", 33 selector: undefined, 34 type: "mouseover" 35 } 36 37 ] 38 }, 39 handle: function(e){}//绑定事件的真正函数 40 }
这个就是jQuery事件对象Data的结构:
events对象:绑定函数类型的集合,每个事件对应一个数组(可能绑定多次)
handler方法:指的是绑定事件的真正函数
我们对红色部分解释一下
data:传递的参数
如:
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click", 100, function(a){ console.log(a.data) })
这个时候,我们看到的data是:data: 100
guid: 唯一的标识符
handler:绑定事件的普通函数
namespace:类型外的二次标志
如:
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click.bbb", function(a){ console.log(1) })
得出:namespace:bbb
应用:比如说我们给document绑定了很多事件,但是我只想取消绑定其中一个函数
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click.bbb", function(a){ console.log(1) }) $clickTrigger.on("click.aaa", function(a){ console.log(2) }) $clickTrigger.off("click.aaa")
点击只会输出“1”
needsContext:默认是undefined,有委托并且委托的元素不是伪类的时候为false,有委托并且委托的元素是伪类的时候为true
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click","i", function(a){ console.log(1) })
这个时候needsContext:false
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click","i:first", function(a){ console.log(1) })
这个时候needsContext:true
origType,type:有的时候由于浏览器的兼容性需要模拟事件,比如说mouseenter
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("mouseenter", function(a){ console.log(1) })
这个时候origType:mouseenter,type:mouseover
selector:
var $clickTrigger = $("#clickTrigger"); $clickTrigger.on("click","i", function(a){ console.log(1) })
selector: "i"
这个就是jQuery事件的Data数据结构及其详细解释。
下次有时间再探讨下jQuery下关于事件的具体代码实现。