Jquery揭秘系列:谈谈bind,one,live,delegate事件及实现
在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数。例如:bind,one,live,delegate等等。
我们先看看他们的定义,直接进入主题:
bind( )方法用于将一个处理程序附加到每个匹配元素的事件上并返回jQuery对象。
.bind(eventType[, evnetData], Handler(eventObject))
其中,参数eventType是一个字符串,包含一个或多个javaScript事件类 型,例如click,submit或自定义事件的名称,指定多个事件类型时用空格分隔各个类型;eventData为Map类型,给出要传递给事件处理程 序的数据,handler指定触发该事件时要执行的函数,eventObject表示事件对象。
.bind()方法将事件处理程序handler附加到匹配元素集合中的每个元素的eventType事件上,如果需要,还可以向事件处理程序传递数据。
live( )方法将一个事件处理程序附加到与当前选择器匹配的所有元素(包含现有的或将来添加的)的指定事件上并返回jQuery对象。
.live(eventType,[eventData],handler)
其中,参数eventType是一个字符串,包含一个或多个javaScript事件类 型,例如click,keydown或自定义事件的名称,eventData是可选参数,为Map类型,给出要传递给事件处理程序的数据,该参数是在 jQuery1.4中添加的;handler是一个函数,当触发该事件时将执行这些函数
.live()方法将事件处理程序handler附加到每个匹配元素(包含当前存在的和将来添加的)的eventType事件上,必要时还可以使用参加eventData向事件处理程序传递数据。
.live()方法是基本的.bind()方法的一个变形,后者可以将事件处理程序附加到 元素·,当调用.bind()时,jQuery对象匹配的元素将被附加上事件处理程序,但以后添加的元素并不会被附加该事件处理程序,因此,还需要对这些 元素再次调用.bind()方法。
.one()方法将事件处理程序附加到匹配元素的指定事件并返回jQuery对象。所附加的事件处理程序最多只能执行一次。
.one(eventType,[eventData],handler(eventObject))
其中,参数eventType是一个字符串,包含一个或多个javaScript事件类 型,例如click,submit或自定义事件的名称,指定多个事件类型时用空格分隔各个类型;eventData为Map类型,给出要传递给事件处理程 序的数据,handler指定触发该事件时要执行的函数,eventObject表示事件对象。
.one()方法与.bind()类似,所不同的是,使用.one()绑定的事件处理程序在执行一次之后将自动取消绑定。
.delegate()方法基于一组特定的根元素将处理程序附加到匹配选择器的所有元素(现有的或将来的)的一个或多个事件上。
.delegate(selector,eventType[,eventData],handler)
其中,参数 selector是一个选择器,用于筛选触发事件的元素;eventType是一个字符串,指定一个或多个JavaScript事件类型(多个事件用空格 分隔),例如click,keydown或自定义事件名称;eventData为映射类型,表示要传递给事件处理程序的数据;handler表示触发该事 件时执行的函数。
.delegate()与.live()类似,可将每个事件的绑定委托给指定的DOM元素。
再说说区别:
-
bind是在dom树加载后,对元素的绑定,属于后期绑定。
-
one是在dom树加载后,对元素的绑定,和bind一样属于后期绑定,但是会在事件执行之后移除元素的绑定事件,事件只执行一次。
-
live 是先把事件绑定在document对象上面,通过事件冒泡,判断当前处于目标状态的元素是不是预绑定的那个元素对象,然后执行事件,属于前期绑定,元素可以是已存在的,也可以是动态添加的。
-
delegate绑定的元素可以是已经存在的,也可以是动态添加的。如果是已经存在的就会选定一个父元素,通过冒泡来触发指定子元素的事件。如果是动态添加的,就以document为父元素来触发冒泡事件。
- (注:这里所说的后期绑定指的是元素已经加载后,进行事件的绑定。前期绑定指的是元素尚未存在,为动态元素添加事件)
这几种方法推荐使用bind和delegate,因为live是绑定事件在document上面,然后通过冒泡查询元素执行事件,很耗性能。
它们的原生js实现 :
(function (context) { var _$ = function (selector) { return new _$.prototype.Init(selector); } _$.prototype = { Init: function () { var arr = Array.prototype.slice.call(arguments); if (arr.length > 0) { if (typeof arr[0] == "string") { this.element = document.getElementById(arr[0]); } else if (Object.prototype.toString.call(arr[0])=="object Object") { this.element = arr[0]; } } }, bind: function (type, fn) { if (this.element) { if (document.addEventListener) { this.element.addEventListener(type, fn, false); } else if (document.attachEvent) { this.element.attachEvent('on' + type, fn); } else { this.element['on' + type] = fn; } } }, unbind: function (type, fn) { if (this.element) { if (document.removeEventListener) { this.element.removeEventListener(type, fn, false); } else if (document.attachEvent) { this.element.detachEvent('on' + type, fn); } else { this.element['on' + type] = null; } } }, one: function (type, fn) { var self = this; if (this.element) { if (document.addEventListener) { this.element.addEventListener(type, function () { self.element.removeEventListener(type, arguments.callee, false); fn(); }, false); } else if (document.attachEvent) { this.element.attachEvent('on' + type, function () { self.element.detachEvent('on' + type, arguments.callee); fn(); }); } else { this.element['on' + type] = function () { self.element['on' + type] = null; fn(); }; } } }, live: function (type, fn) { var self = this; if (document.addEventListener) { document.addEventListener(type, function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.id == self.element.id) { fn(); } }, false); } else if (document.attachEvent) { document.attachEvent('on' + type, function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.id == self.element.id) { fn(); } }); } else { document['on' + type] = function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.id == self.element.id) { document['on' + type] = null; fn(); } }; } }, delegate: function (flag, type, fn) { var self = this; if (document.addEventListener) { self.element.addEventListener(type, function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.tagName.toLowerCase() == flag) { fn(); } }, false); } else if (document.attachEvent) { self.element.attachEvent('on' + type, function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.tagName.toLowerCase() == flag) { fn(); } }); } else { self.element['on' + type] = function (e) { var evt = e || window.event; var target = evt.srcElement || evt.target; if (target.tagName.toLowerCase() == flag) { fn(); } }; } } } _$.prototype.Init.prototype = _$.prototype; context.$ = _$; })(window);
这里就是一些兼容性代码,阅读起来没啥难度,如果有描述不清楚的地方,可以留言。