关于事件传播机制
事件:
JavaScript 和 HTML的交互是通过事件实现的。
事件是某个行为或触发,比如点击,鼠标移动:
- 当用户点击鼠标时
- 当网页已加载时
- 当图像已经加载时
- 当鼠标移动到元素上时
- 当用户触发按键时
事件流
事件冒泡
点击div区域时,从下往上往父元素传播
事件捕获
点击div时先从树根Document开始捕获,再一层层传给子元素
DOM事件流
DOM2级事件规定事件流包括3个阶段,事件捕获阶段,处于目标阶段,时间冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是世纪目标接受事件,最后是冒泡阶段。
相当于先进行一次捕获阶段,再到冒泡阶段
阻止传播
阻止传播一般使用stopPropagation取消事件的进一步冒泡或者捕获 也就是取消进一步的事件捕获或冒泡,防止再触发定义在别的节点上的监听函数,但不包括再当前节点上新定义的事件监听函数。 例: 我们可以在button的事件处理程序中调用stopPropagation()从而避免注册在body上的事件发生。 若是注释掉e.stopPropagation();在点击button的时候,由于事件冒泡,body的click事件也会触发,但是调用后这句后,事件会停止传播。 undefined ##### 取消默认行为 preventDefault方法取消浏览器对当前事件的默认行为,
比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。
该方法生效的前提是,事件的cancleable属性为true, 如果为false,则该方法没有效果。
该方法不会阻止事件的进一步传播,只是该事件的默认方法不会执行。
例:
可以为文本框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。
keypress监听函数,只能输入小写字母,否则输入事件的默认事件(写入文本框)将本取消。
1 2 3 4 5
| function checkName(e){ if(e.charCode < 97 || e.charCode > 122){ e.preventDafault(); } }
|
事件代理
事件代理就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。(delegation)。
我们知道当一个元素上的事件被触发时,比如说点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。(事件冒泡)
因此我们可以给父元素田间事件监听器,子元素添加事件,事件触发冒泡上来,可以把多个子元素的事件进行统一处理。
这叫做事件的代理。
例:
上面代码的click事件的监听函数定义在ul节点,但是实际上,它处理的是子节点li的click事件。这样的好处是,只要定义一个监听函数,就能处理多个子节点的事件,且以后再添加子节点,监听函数依然有效。
1 2 3 4 5 6
| var ul = document.querySelector('ul'); ul.addEventListener('click', function(event){ if(event.target.tagName.toLowerCase() === 'li'){ } })
|
事件传播过程的DEMO,演示阻止传播的效果
演示地址
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>Homework</title> </head> <body> <button id="btn">click</button> <div class="container"> container <div class="box"> box <div class="target"> target </div> </div> </div> </body> </html>
|
CSS
1 2 3 4 5 6 7
| .container, .box, .target { border: 2px solid pink; padding: 10px; }
|
JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| var btn = document.querySelector('#btn');
btn.onclick = function (e){ console.log(e); };
btn.addEventListener('click', function(e){ console.log(this); });
document.querySelector('.container').addEventListener('click', function(e){ console.log('container click.. in 捕获阶段'); }, true);
document.querySelector('.box').addEventListener('click', function(e){ console.log('box click.. in 捕获阶段'); }, true);
document.querySelector('.target').addEventListener('click', function(e){ console.log('target click.. in 捕获阶段'); }, true);
document.querySelector('.container').addEventListener('click', function(e){ console.log('container click.. in 冒泡阶段'); });
document.querySelector('.box').addEventListener('click', function(e){ e.stopPropagation(); console.log('box click.. in 冒泡阶段'); });
document.querySelector('.target').addEventListener('click', function(e){ console.log('target click.. in 冒泡阶段'); });
|