JS事件流及事件委托

35 阅读1分钟
1.js完整事件流

从下图可以看出一个完整的事件流是从window开始,最后回到window的一个过程

事件流被分为3个阶段:1-5捕获阶段,5-6:目标阶段,6-10:冒泡阶段

image.png

加入事件 addEventListener 移除事件 removeEventListener

<body>
  <div id="div" style="height: 100px;background: grey;"></div>
</body>

<script>
  var eleDiv = document.querySelector('#div');
  var i = 0;

  // 捕获 
  // 3号事件 
  document.body.addEventListener('click',function(){
    console.log('捕获-阶段3:body')
  },{
    // 默认值是不使用捕获,即冒泡(这里可以去看addEventListener参数说明)
    capture:true
        });

  // 4号  event.stopPropagation()可以阻止事件的传递(事件流任何阶段都可使用)
  eleDiv.addEventListener('click',function(event){
    console.log('捕获-阶段4:div')
            if(i++ % 2 !== 0) {
    event.stopPropagation(); // 阻止事件传递
            }
        },{
    // 默认值是不使用捕获,即冒泡
    capture:true
        })

  // 冒泡
  // 7号事件
  eleDiv.addEventListener('click',function(){
    console.log('捕获-阶段7:div')
  },{
    // 冒泡(默认值)
    capture:false
        });
  // 8号事件
  document.body.addEventListener('click',function(){
    console.log('捕获-阶段8:body')
  },{
    // 冒泡(默认值)
    capture:false
        })
</script>
2.事件委托

靠父元素body来代理其子元素div的事件

// 这里两秒后添加一个div节点
setTimeout(function(){
  document.body.innerHTML += '<div id="div" class="abc" style="height: 100px;background: grey;"></div>'
},2000);
//获取div节点
var eleDiv = document.querySelector('#div');

// 由于前两秒子元素div还不存在,可以靠父元素body来代理div的事件(此刻div不存在)
// 实现的效果是点击div会移除他本身
document.body.addEventListener('click', function (event) {
  console.log(this); // 固定body
  console.log(event.currentTarget); // 固定body
  console.log(event.target); // 实际触发事件的元素(div或者body),所以我们确定用这个来表示实际触发事件的元素
  // 获取事件触发对象
  var target = event.target;
  if (target.classList.contains('abc')) {
    console.log('找到了子元素点击的事件');
    // var id = target.getAttribute('id');// 这里是获取节点id的方法
    target.remove();
  }
});