区别:
- bind只能给符合条件的元素本身添加事件
- on可以将子元素的事件委托给父元素进行处理,而且可以给动态添加的元素加上绑定事件,也就是对于新添加的元素如果是on绑定,符合条件的新元素也会绑定事件,
我们来看一段代码(例一)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 <script src="../js/jquery-1.11.3.min.js"></script> 7 </head> 8 <body> 9 <ul> 10 <li>第一个子元素<li/> 11 <li>第二个子元素<li/> 12 <li>第三个子元素<li/> 13 </ul> 14 <script> 15 16 /* $('ul').on('click','li', function () { 17 console.log($(this).text()); 18 }); */ 19 $('ul li').bind('click', function () { 20 console.log($(this).text()); 21 }); 22 $('ul').append('<li>第四个子元素<li>'); 23 </script> 24 </body> 25 </html>
当我们执行这段代码时,会发现“第四个子元素”点击没有console.log,其他li都成功了;
然后我们在注释掉 bind这段代码,开启click,重新执行这段代码,发现第四个子元素”点击有console.log内容;
新添加的 “第四个子元素” 符合条件,就也绑定了click;
详细说就是:
执行事件委托的时候只有子元素(本文中的li)会触发事件,而代为执行的父元素(本文中为ul)不会触发事件。
也可以这么写:
1 $(function(){ 2 $("#lists").delegate("li","click",function(event){ 3 var target = $(event.target); 4 target.css("background-color","red"); 5 }) 6 })
bind()方法同原生的JavaScript实现方法一样,当父元素代子元素执行事件时,父元素也会触发事件,所以我们需要判断一下触发事件的元素名。此外,用bind()方法给元素绑定事件的时候要注意,它只能给已经存在DOM元素添加事件,不能给未来存在DOM。
1 $("ul li").bind("click",function(event){ 2 var target = $(event.target); 3 if(target.prop("nodeName")=="LI"){ 4 target.css("background-color","red");} 5 }) 6 $('ul').append('<li>第四个子元素<li>');
元素添加添加事件。如果要频繁地添加DOM元素,并且给新添加的DOM元素绑定事件的话,用live(),delegate(),on()等方法。鉴于jQuery从1.7之后就不推荐live()和delegate()方法了,所以大家还是使用on()方法吧。
再看一个概念:js事件冒泡
javascript的事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止,这就是事件冒泡现象。
(例二)
1 <div id="col"> <p> <a id="btn" href="#">button</a> </p></div> 2 <script> 3 let btnclick = document.getElementById('col');btnclick.onclick=function(e){ console.log('1');}; 4 <script>
执行结果,当点击a标签时,也可以在控制台输出1;但是a元素并没有绑定click事件,这就是由于事件冒泡的现象,事件逐级传播给先辈元素,点击li——ul,然后就可以执行对应的div绑定的事件。
on 绑定click就出现了 事件冒泡;
on方式是一种事件委托方式;
******************************************************************那么**************************************************************************
一:什么是事件委托?
事件委托是利用事件冒泡,只指定一个事件处理程序来管理某一类型的所有事件。
二:为什么要用事件委托?
1.在JavaScript中添加到页面上的事件处理程序的个数直接关系到页面的整体运行性能。为什么呢?因为,每个事件处理函数都是对象,对象会占用内存,内存中的对象越多,性能就越差。此外,必须事先指定所有的事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。
2.对有很多个数据的表格以及很长的列表逐个添加事件,简直就是噩梦。所以事件委托,能极大地提高页面的运行性能,减少开发人员的工作量。
再看一个概念:js事件捕获,(事件冒泡的逆过程)
还是上面的例子,改成事件捕获
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 <script src="../js/jquery-1.11.3.min.js"></script> 7 </head> 8 <body> 9 <ul> 10 <li id='testli'>第一个子元素<li/> 11 <li>第二个子元素<li/> 12 <li>第三个子元素<li/> 13 </ul> 14 <script> 15 16 /* $('ul').on('click','li', function (event) { 17 console.log($(this).text()); 18 event.stopPropagation() 19 }); */ 20 /* $('ul li').bind('click', function () { 21 console.log($(this).text()); 22 }); */ 23 $('ul').append('<li>第四个子元素<li>'); 24 var lis = document.getElementsByTagName("li"); 25 for(var i=0;i<lis.length;i++){ 26 lis[i].addEventListener("click",function(){ 27 alert($(this).html()); 28 29 },true) 30 } 31 var uls = document.getElementsByTagName("ul"); 32 uls[0].addEventListener("click",function(){ 33 alert($(this).html()); 34 35 },true) 36 </script> 37 </body> 38 </html>
事件捕获:
在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <ul> 元素的点击事件先触发 ,然后再触发 <li> 元素的点击事件。
addEventListener() 方法可以指定 "useCapture" 参数来设置传递类型:
默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。
最后的最后:附上一张图;
补充:
js停止冒泡:stopPropagation
$('ul').on('click','li', function (event) {
console.log($(this).text());
event.stopPropagation()
});
on 解绑click :off("click",function(){...});
移除捕获:
element.removeEventListener(type,handler,false/true)
var uls = document.getElementsByTagName("ul");
uls[0].removeEventListener("click",function(){
alert($(this).html());
},true)