好!欢迎访问迷津渡口 现在时间是: 天气 °C ~ °C

迷津渡口

越感到迷惑 越接近真理

事件捕获、事件冒泡和事件委托

事件捕获和事件冒泡

事件捕获和事件冒泡是浏览器处理事件的两种顺序,IE9之前IE只有事件冒泡,IE9+、Chrome、火狐等两者皆有。


事件捕获是从根元素往下找,直到找到事件触发的真正DOM元素,因此事件触发顺序为外层事件到内层事件。


事件冒泡是从实际触发事件的元素出发,事件向外层元素冒泡,直到根元素,因此事件触发顺序为内层事件到外层事件。


支持两者的浏览器处理顺序为:

  1. 优先查找事件捕获,若注册了捕获事件,则从最外层开始触发;

  2. 事件捕获完成后,找到触发事件的最内层元素,向外进行事件冒泡


默认:事件冒泡

点击div4,未注册捕获事件,因此处理顺序为触发事件的最内层向外冒泡,弹出顺序为div4,div3,div2,div1

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>默认情况-事件冒泡</title>
<style>
#div1 {
  width: 400px;
  height: 400px;
  background-color: red;
}
#div2 {
  width: 300px;
  height: 300px;
  background-color: blue;
}
#div3 {
  width: 200px;
  height: 200px;
  background-color:green;
}
#div4 {
  width: 100px;
  height: 100px;
  background-color: gold;
}
.right-bottom {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}
</style>
</head>
<body>
<div id="div1" class="right-bottom">
  <div id="div2" class="right-bottom">
    <div id="div3" class="right-bottom">
      <div id="div4"></div>
    </div>
  </div>
</div>
<script>
var div1 = document.querySelector('#div1'),
  div2 = document.querySelector('#div2'),
  div3 = document.querySelector('#div3'),
  div4 = document.querySelector('#div4');
  
div1.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
div2.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
div3.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
div4.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
</script>
</body>
</html>


修改为事件捕获:

点击div4,都注册了捕获事件,从最外层开始捕获触发事件,因此弹出顺序为div1,div2,div3,div4

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自定义-事件捕获</title>
<style>
#div1 {
  width: 400px;
  height: 400px;
  background-color: red;
}
#div2 {
  width: 300px;
  height: 300px;
  background-color: blue;
}
#div3 {
  width: 200px;
  height: 200px;
  background-color:green;
}
#div4 {
  width: 100px;
  height: 100px;
  background-color: gold;
}
.right-bottom {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}
</style>
</head>
<body>
<div id="div1" class="right-bottom">
  <div id="div2" class="right-bottom">
    <div id="div3" class="right-bottom">
      <div id="div4"></div>
    </div>
  </div>
</div>
<script>
var div1 = document.querySelector('#div1'),
  div2 = document.querySelector('#div2'),
  div3 = document.querySelector('#div3'),
  div4 = document.querySelector('#div4');
  
div1.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
div2.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
div3.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
div4.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
</script>
</body>
</html>


混合事件捕获和事件冒泡:

给div1和div3加上事件捕获,则点击div4,先从外层向内层进行事件捕获的触发,先弹出div1,div3,然后进入触发事件的最内层元素,开始进行事件冒泡,再弹出div4,div2,因此触发顺序为div1,div3,div4,div2

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>混合事件捕获和事件冒泡</title>
<style>
#div1 {
  width: 400px;
  height: 400px;
  background-color: red;
}
#div2 {
  width: 300px;
  height: 300px;
  background-color: blue;
}
#div3 {
  width: 200px;
  height: 200px;
  background-color:green;
}
#div4 {
  width: 100px;
  height: 100px;
  background-color: gold;
}
.right-bottom {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}
</style>
</head>
<body>
<div id="div1" class="right-bottom">
  <div id="div2" class="right-bottom">
    <div id="div3" class="right-bottom">
      <div id="div4"></div>
    </div>
  </div>
</div>
<script>
var div1 = document.querySelector('#div1'),
  div2 = document.querySelector('#div2'),
  div3 = document.querySelector('#div3'),
  div4 = document.querySelector('#div4');
  
div1.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
div2.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
div3.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
}, true)
div4.addEventListener('click', function(event) {
  alert(event.currentTarget.id)
})
</script>
</body>
</html>


事件委托

事件委托是利用事件冒泡的原理,将子元素触发的事件冒泡到父元素进行处理,从而无需进行大量子元素的事件绑定,同时子元素动态变化时也无需重新绑定事件,因此大大提高了效率,优化了处理的方法。

例子:列表项鼠标悬停时字体变红,点击按钮可新增一个列表项

不使用事件委托的方式:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>不使用事件委托的例子</title>
</head>
<body>
<ul>
  <li>111111</li>
  <li>222222</li>
  <li>333333</li>
</ul>
<button id="add-item-btn">新增列表项</button>
<script>
var lis = document.querySelectorAll('li')
lis.forEach(function(item) {
  item.addEventListener('mouseover', function() {
    item.style.color = 'red'
  })
  item.addEventListener('mouseout', function() {
    item.style.color = 'black'
  })
})

var btn = document.querySelector('#add-item-btn')
var ul = document.querySelector('ul');
btn.addEventListener('click', function() {
  var item = document.createElement('li')
  item.innerText = '444444'
  /*需要重新绑定事件*/
  item.addEventListener('mouseover', function() {
    item.style.color = 'red'
  })
  item.addEventListener('mouseout', function() {
    item.style.color = 'black'
  })
  ul.appendChild(item)
})
</script>
</body>
</html>


使用事件委托的方式:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>使用事件委托的例子</title>
</head>
<body>
<ul>
  <li>111111</li>
  <li>222222</li>
  <li>333333</li>
</ul>
<button id="add-item-btn">新增列表项</button>
<script>
var btn = document.querySelector('#add-item-btn')
var ul = document.querySelector('ul');
ul.addEventListener('mouseover', function(event) {
  if (event.target.tagName.toUpperCase() === 'LI') {
    event.target.style.color = 'red'
  }
})
ul.addEventListener('mouseout', function(event) {
  if (event.target.tagName.toUpperCase() === 'LI') {
    event.target.style.color = 'black'
  }
})
btn.addEventListener('click', function() {
  var item = document.createElement('li')
  item.innerText = '444444'
  /*不需要重新绑定事件*/
  ul.appendChild(item)
})
</script>
</body>
</html>


事件委托的方式代码简单,效率较高~

点赞4
   支持一下
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
 点赞
 签到
 表情
 图片
 代码
提交评论

清空信息
关闭评论
520.shanxin99.com
 520.shanxin99.com 2018-09-10 21:17回复
#2
首先 恭喜您很幸运地迈入互联网+网站+推广新时代,如果你还没有一份高额稳定的5000元至100000元的月收入,那我劝你往下看!如果你有一份稳定低收入工作,苦于想找一个轻松的第二职业,那我还是劝你耐心看下去!你是否想拥有属于自己的家庭公司……如果您想在未来的90天内最少赚到10万元甚至更多!现在正是一个正当合法的好机会。请仔细看完下面的内容...

●职业要求:
1、有上网条件(在家中、办公室、网吧等地);
2、每天能有1-2小时上网时间;
3、有网络应用的基础(会上论坛发贴子、发电子邮件、与客户QQ微信沟通等)。

●产品套餐---网站管理系统:不用写代码,只要会打字就能做网站。
您会拥有一套和本站一样精美、功能强大、完全属于您自己的网站。作为站长,您可以展示企业简介、公司招聘、商户产品、成功案例、新闻动态和留言互动等,只要会打字就能做网站。网站免费上百度首页。

● 加盟合作---市场运营事业:不一定改变命运,但百分之百可以赚到钱。
作为白银代理商,您的工作任务就是在网络(朋友圈/论坛/贴吧/留言本/QQ群)或者报纸媒体或者身边推广您的网站,赚取巨额市场运营奖金,或者发布商品赚钱,或者赚广告费等等,如果您想在未来的90天内最少赚到10万元甚至更多!现在正是一个正当和合法的好机会。

●收入待遇:
5000元以上/月。奖金倍增,收入直线上升! 做得好年薪可达100万元以上。

有意者请登录注册http://shanxin99.com/520/zc.asp

八十年代初,摆个地摊就能发财,可很多人不敢。
九十年代初,买支股票就能挣钱,可很多人不信。
二十一世纪,开个网站就能赚钱,可很多人不试。
现在是互联网+网站+推广新时代,参与善心久久市场运营事业,就能月赚数万元,你还想错过吗?有意者请到 http://520.shanxin99.com 注册开通网站。
人生成功的秘诀是当好机会来临时,立刻抓住它.——狄斯累利
点赞成功!点赞时间:2018年9月10日 晚上9时18分38秒,赠人玫瑰,手有余香!
520.shanxin99.com
 520.shanxin99.com 2018-09-10 20:56回复
#1
<a href=http://shanxin99.com target=_blank title=自动上友链和网页秒收录>善心久久自动秒收录</a>
顶部留言底部
 00:00/00:00
我想和你虚度时光 - 花房姑娘(9)
  1. 我想和你虚度时光
  2. 花房姑娘
  3. 恋恋风尘
  4. 我喜爱一切不彻底的事物
  5. 我的心里是满的
  6. Long Way
  7. 给少年的歌
  8. 晴日共剪窗
  9. 天上的月你的脸