理解事件冒泡、事件捕获、事件代理

对于事件的传播机制,Netscape Communicator采用的是事件捕获(event capture),IE9、Safari、Chrome、Opera和Firefox采用的是事件冒泡(event bubbling),下面我们通过案例来具体理解,代码使用chrome浏览器进行测试,先给出HTML和CSS文件:



  
  理解事件冒泡与事件捕获
  


      
外面:id为1
中间:id为2
里面:id为3

请点击复选框控件

一、capture参数
在chrome中默认以冒泡的形式,capture为false,可以直接指定第三个参数为false,相当于{capture:false}
function logText(e) {
            console.log(this.classList.value);
          }
 divs.forEach(div => div.addEventListener('click', logText));
点击id=one元素 : one;
点击id=2的元素 : two one
点击id=3的元素,three two one
理解事件冒泡、事件捕获、事件代理_第1张图片
function logText(e) {
            console.log(this.classList.value);
          }
          divs.forEach(div => div.addEventListener('click', logText, {
            capture: true,
    }));
点击id=one元素 : one;
点击id=2的元素 :one two
点击id=3的元素 : one two three
理解事件冒泡、事件捕获、事件代理_第2张图片
二、 e.stopPropagation():阻止 捕获和冒泡阶段中当前事件的进一步传播
function logText(e) {
            console.log(this.classList.value);
             e.stopPropagation(); // one ; two ; three
          }
  divs.forEach(div => div.addEventListener('click', logText));
点击id=one元素 : one
点击id=2的元素 :two
点击id=3的元素 : three
理解事件冒泡、事件捕获、事件代理_第3张图片
function logText(e) {
             console.log(this.classList.value);
             e.stopPropagation();/
           }
 divs.forEach(div => div.addEventListener('click', logText, {
             capture: true,
           }));
事件只会在第一个捕获的元素上面触发
点击id=one元素 : one
点击id=2的元素 :one
点击id=3的元素 : one
理解事件冒泡、事件捕获、事件代理_第4张图片
三、event.preventDefault():
(1)如果事件可取消,则取消该事件,而不停止事件的进一步传播。preventDefault 方法不会阻止该事件的进一步冒泡. event.stopPropagation 方法才有这样的功能.
document.querySelector("#id-checkbox").addEventListener("click", function(event){
                alert("preventDefault会阻止该复选框被勾选.")
                event.preventDefault();//无法勾选选项框
                console.log(event.defaultPrevented);//true
                //阻止该复选框被勾
 }, false);
(2)使用passive:false来禁止e.preventDefault()的调用
document.querySelector("#id-checkbox").addEventListener("click", function(event){
                event.preventDefault();//可以勾选选项框
                console.log(event.defaultPrevented);//false
            }, {passive:true});//Unable to preventDefault inside passive event listener invocation.
四、事件代理:
1、原理:事件冒泡,为外层元素指定一个事件处理程序,就可以管理某一类型的所有事件。
(1)event.target和event.currentTarget:在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this、currentTarget 和 target包含相同的值:
(2)event.eventPhase :可以用来确定事件当前正位于事件流的哪个阶段。如果是在捕获阶
段调用的事件处理程序,那么eventPhase 等于1;如果事件处理程序处于目标对象上,则event-
Phase 等于2;如果是在冒泡阶段调用的事件处理程序,eventPhase 等于3。这里要注意的是,尽管
“处于目标”发生在冒泡阶段,但eventPhase 仍然一直等于2
function logText(e) {
console.log(e.currentTarget);
console.log(e.currentTarget === this);
console.log(e.target);
}
document.querySelector('.one').addEventListener('click',logText, false);
依次点击id为1、2、3的div控制台会输出以下数据:
理解事件冒泡、事件捕获、事件代理_第5张图片
下面通过使用{capture:true}参数了解event.eventPhrase,尽管“处于目标”发生在捕获阶段,但eventPhase 仍然一直等于2
function logText(e) {
console.log(e.currentTarget);
console.log(e.currentTarget === this);
console.log(e.target);
console.log(e.eventPhase);
}
document.querySelector('.one').addEventListener('click',logText,{capture:true});
依次点击id为1、2、3的div控制台会输出以下数据:
理解事件冒泡、事件捕获、事件代理_第6张图片
以上是本人对事件代理、事件捕获和事件代理的理解,不当之处,敬请指出:
想获取Demos的完整代码请戳 这里:

你可能感兴趣的:(javascript)