今天在和同事聊天的时候聊到了关于JQuery中bind事件和live事件的使用,感觉在日常代码中大多使用的都是bind很少接触live,一直以来对于bind的事件绑定都挺顺手的就没想着去调整使用live,今天因为这个讨论重新了解JQuery的事件绑定机制,发现原来bind方法一直都存在缺陷,而live方法相当于是对bind的补足。
首先要说的还是总结,JQuery对于事件的绑定大概有三种模式:
一:直接使用内置方法绑定,如$("#clickThis").click(function(){});
二:使用bind来绑定事件,如$("#clickThis").bind('click',function(){});
三:使用live来绑定事件,如$("#clickThis").live('click',function(){});
第一种方法很明显,一看就能明白是给id为clickThis的控件绑定点击事件,不细说了。
第二种方法和第三种方法在代码上看起来基本是一模一样的,但实质上却存在一定的差别。就像我一开始说的,live方法是对bind方法的补足,在我们实际项目过程中,有的控件在页面加载的时候是不存在的,只有在用户触发某一个方法以后才会生成这么一个控件,对于这样的控件上绑定事件,bind就没有办法实现了。原因是bind方法会在页面加载的时候就去判断是否存在目标控件,如果存在可以绑定事件,如果不存在就无法绑定事件上去。这个判断只有在页面加载的时候才会进行,也就是说,当页面加载的时候还不存在你要控制的目标控件,那么你的bind事件就是一句冗余代码,没有丝毫作用的,而当用户交互之后生成了这个控件,这个控件同样绑定不了bind事件。这个需求就在live方法里面被补充了,live方法在本质上完成的是和bind方法相同的工作,只是live方法在对目标控件是否存在的判断上是“滞后”的。
live方法是基于“事件委托”的,所谓的“事件委托”指的是,绑定在祖先元素上的事件可以在其后代元素上进行使用。在页面加载到live方法的时候,live方法会去判断DOM中是否存在目标控件节点,如果没有找到,就一层一层的向上冒泡,将事件“委托”到DOM根节点上。
举个栗子:在ready中有:
$(".ClickThis").live('click',function(){alert("Success!")});
$("body").append("<div class='ClickThis'>测试live</div>");
在我们点击“测试live”的div时会执行以下过程:
一、生成一个click事件,并在div上寻找对应的事件;
二、由于在div上找不到click事件的绑定,寻找会一直随着DOM树向上查找
三、在DOM根节点找到了click事件的绑定
四、找到这个绑定以后开始执行绑定事件
五、执行的第一步就是返回去查看是否已经存在了目标控件,如果是目标控件触发的click则执行。
看到这里,是不是觉得live方法比bind要强大的多了,是不是很想不清楚为什么bind方法没有被live方法给替换掉而是依然存在,或者说为什么live方法不直接在bind上面进行补足而是重开了一个新的方法名。其实实际上,bind方法还是存在自己的优势的。比如说:
(1)bind方法可以绑定任何JavaScript的事件,而live方法在jQuery1.3的时候只支持click, dblclick, keydown, keypress,
keyup,mousedown, mousemove, mouseout, mouseover, 和 mouseup.在jQuery 1.4.1中,甚至也支持 focus 和 blue事件了(映射到更合适,并且可以冒泡的focusin和focusout上)。另外,在jQuery 1.4.1中,也能支持hover(映射到"mouseenter mouseleave")。
(2)live() 并不完全支持通过DOM遍历的方法找到的元素。取而代之的是,应当总是在一个选择器后面直接使用 .live()方法。
(3)当一个元素采用live方法进行事件的绑定的时候,如果想阻止事件的传递或冒泡,就要在函数中return false,仅仅调用stopPropagation()是无法实现阻止事件的传递或者冒泡的