JavaScript中绑定事件的方法主要有三种:
- 在DOM元素中直接绑定
- JavaScript代码中直接绑定
- 绑定事件监听函数
在DOM元素中直接绑定
我们可以在DOM元素上绑定onclick、onmouseover、onmouseout、onmousedown、onmouseup、ondblclick、onkeydown、onkeypress、onkeyup等。但不符合样式、行为、结构 三者分离的概念。也就是直接在html标签中通过 onXXX=“” 来绑定。举个例子:
<input type="button" value="点我呦" onclick="alert("hello world!")"/>
<!--或者-->
<input type="button" value="点我呦" onclick="testAlert()">
<script type="text/javascript">
function testAlert(){
alert("hello world!");
}
</script>
在JavaScript中通过查找DOM对象,对其绑定,elementObject.οnclick=function(){} 的格式,举例如下:
JavaScript代码中直接绑定
<input type="button" value="点我呦" id="demo">
<script type="text/javascript">
document.getElementById("demo").onclick=function testAlert(){
alert("hello world!");
}
</script>
绑定事件监听函数
这里需要了解addEventListener()和attachEvent()的函数语法。
-
elementObject.addEventListener(eventName,handle,useCapture) (支持主流浏览器、以及IE9.0及以上)
- eventName:要绑定的事件名称。注意写法,比如点击事件,写成click,而不是onclick.
- handle: 处理事件的函数名。但是写法上没有小括号。
- useCapture:Boolean类型,是否使用捕获,一般用false,具体涉及到的会在后边总结。
-
elementObject.attachEvent(eventName,handle);(仅支持IE8及以下)
从网上找到了一个兼容的好办法,相比较if。。else语句,这个方法用的是try..catch错误处理语句,可以避免浏览器出现错误提示。
function addEvent(obj,type,handle){
try{
obj.addEventListener(type,handle,false);
}catch(e){
try{
obj.attachEvent('on'+type,handle);
}
catch(e){
obj['on' + type]=handle;//早期浏览器
}
}
}
JQuery中绑定事件的几种方法。
jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off.
bind(type,[data],function(eventObject))
bind是使用频率较高的一种,作用就是在选择到的元素上绑定特定事件类型的监听函数,参数的含义如下:
- type:事件类型,如click、change、mouseover等;
- ata:传入监听函数的参数,通过event.data取到。可选;
function:监听函数,可传入event对象,这里的event是jQuery封装的event对象,与原生的event对象有区别,使用时需要注意.
bind的特点就是会把监听器绑定到目标元素上,有一个绑一个,在页面上的元素不会动态添加的时候使用它没什么问题。但如果列表中动态增加一个“列表元素5”,点击它是没有反应的,必须再bind一次才行。要想不这么麻烦,我们可以使用live。
jQuery还有一种事件绑定的简写方式如a.click(function(){});、a.change(function(){});等,它们的作用与bind一样,仅仅是简写而已。
live(type, [data], fn)
live的参数和bind一样,它又有什么蹊跷呢,我们还是先瞄一眼源码:
live: function( types, data, fn ) {
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
}
可以看到live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。这个context是什么东西呢?其实就是元素的限定范围,所以也就认为这个context通常就是document了,即live方法把监听器绑定到了 document上了。不把监听器直接绑定在元素上,你是不是想起事件委托机制来了呢?若没有,可以点击这里回忆一下。live正是利用了事件委托机制来 完成事件的监听处理,把节点的处理委托给了document。在监听函数中,我们可以用event.currentTarget来获取到当前捕捉到事件的节点。
live存在那样的缺点,所以我们就思考,既然老爷子负担那么重,可不可以别把监听器绑定在document上呢,绑定在就近的父级元素上不就好了。顺应正常逻辑,delegate诞生了。
delegate(childSelector,event,data,function)
delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)
当点击鼠标时,隐藏或显示 p 元素:
$("div").delegate("button","click",function(){
$("p").slideToggle();
});
参数多了一个selector,用来指定触发事件的目标元素,监听器将被绑定在调用此方法的元素上。看看源码:
delegate: function( selector, types, data, fn ) {
return this.on( types, selector, data, fn );
}
on(event,childSelector,data,function)
on() 方法在被选元素及子元素上添加一个或多个事件处理程序。
向 <p> 元素添加 click 事件处理程序:
$(document).ready(function(){
$("p").on("click",function(){
alert("段落被点击了。");
});
});
演变过程
-
.bind()是直接绑定在元素上(),jquery1.7版本以前比较受推崇,1.7版本出来之后,官方已经不推荐用bind(),替代函数为on(),这也是1.7版本新添加的函数,同样,可以用来代替live()函数,live()函数在1.9版本已经删除;
-
.delegate()则是更精确的小范围使用事件代理,性能优于.live()(在Jquery1.7中已经移除)
-
.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document
DOM节点上。和.bind()的优势是支持动态数据。(在Jquery1.7中已经移除,相应die()也移除)
live()函数和delegate()函数两者类似,但是live()函数在执行速度,灵活性和CSS选择器支持方面较delegate()差些 -
.on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制(在Jquery1.7中添加,相应off()也添加)
注意点
一般on之前,都off一下,这样可以防止事件重复绑定。但是如果本来就已经绑定了多次(不同的处理函数),但是你不知道,就会出现问题。
案例:
定位BJUI框架中,selectpicker的on的处理函数。源代码里面,没有off,别人是有深意的。