导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

⭐️ 冒泡和捕获

子级会向父级传递自己的事件,如果父级也有相同事件则响应

<style>
  .wrapper {
    width: 150px;
    height: 150px;
    background-color: aqua;
  }
  .outer {
    width: 100px;
    height: 100px;
    margin-left: 150px;
    background-color: bisque;
  }
  .inner {
    width: 75px;
    height: 75px;
    margin-left: 100px;
    background-color: blueviolet;
  }
</style>

<div class="wrapper">
  <div class="outer">
    <div class="inner"></div>
	</div>
</div>

<script>
var wrapper = document.getElementsByClassName('wrapper')[0];
var outer = document.getElementsByClassName('outer')[0];
var inner = document.getElementsByClassName('inner')[0];
  
wrapper.addEventListener('click', function() {
	console.log('wrapper-冒泡');
}, false);
outer.addEventListener('click', function() {
	console.log('outer-冒泡');
}, false);
inner.addEventListener('click', function() {
	console.log('inner-冒泡');
}, false);

wrapper.addEventListener('click', function() {
	console.log('wrapper-捕获');
}, true);
outer.addEventListener('click', function() {
	console.log('outer-捕获');
}, true);
inner.addEventListener('click', function() {
	console.log('inner-捕获');
}, true);
</script>

新版chrome:

Untitled

旧版 chrome 和新旧版 Firefox、Safari 都还是顺序执行:

Untitled

⭐️ 阻止事件冒泡

w3c: e.stopPropagation(); -> Event.prototype

oDiv.addEventListener('click', function(e) {
	var e = e || window.event;
  e.stopPropagation(); 
}, false);

IE: e.cancelBubble = true;

oDiv.addEventListener('click', function(e) {
	var e = e || window.event;
  e.cancelBubble = true;
}, false)

⭐️ 封装阻止事件冒泡

function cancelBubble(e) {
  var e = e || window.event;
  if (e.stopPropagation) {
    e.stopPropagation();
  } else {
    e.cancelBubble = true;
  }
}

案例

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    .wrapper {
      position: relative;
      width: 300px;
      height: 300px;
      background-color: green;
    }

    .apply {
      position: absolute;
      bottom: 15px;
      right: 15px;  
      width: 80px;
      height: 30px;
      background-color: red;
      color: #fff;
      line-height: 30px;
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="apply">立即申请</div>
  </div>

  <script type="text/javascript">
  // w3c: e.stopPropagation(); -> Event.prototype
  // IE: e.cancelBubble = true;
  var wrapper = document.getElementsByClassName("wrapper")[0],
      apply = document.getElementsByClassName("apply")[0];

  wrapper.addEventListener("click", function() {
    console.log("进入详情");
  }, false);
  apply.addEventListener("click", function(e) {
    console.log("立即申请");
    cancelBubble(e);
  }, false);

  // 取消冒泡
  function cancelBubble(e) {
    var e = e || window.event;
    if (e.stopPropagation) {
      e.stopPropagation();
    } else {
      e.cancelBubble = true;
    }
  }
  </script>
</body>
</html>

Untitled

⭐️ 取消默认事件

取消右键菜单

return false (不支持 addEventListener 中使用)

document.oncontextmenu = function(e) {
	var e = e || window.event;
  return false;
}

e.preventDefault() (IE9不兼容):

document.oncontextmenu = function(e) {
	var e = e || window.event;
  e.preventDefault();
}

e.returnValue = false; (IE9以下):

document.oncontextmenu = function(e) {
	var e = e || window.event;
  e.returnValue = false
}

阻止 a 标签跳转

<a href="">hh</a>
a.onclick = function(e) {
	e.preventDefault();
}