JavaScript:事件源与事件流

事件源

在事件中,当前操作的那个元素就是事件源。比如网页元素中 input 有 onclick 事件,当点击 input 发送 onclic 事件时,事件源就是 input。

常见事件源

(鼠标) 事件描述
onclick鼠标单击对象时触发
ondblclick鼠标双击对象时触发
onmousedown鼠标按钮被按下时触发
onmousemove鼠标被移动时触发
onmouseout鼠标离开监听该事件的元素或子元素时触发
onmouseover鼠标移动到监听该事件的元素或子元素时触发
onmouseup鼠标松开时触发
(键盘) 事件描述
onkeydown键盘按下
keypress键盘按住
keyup键盘松开
(表单控件) 事件描述
onblur失去焦点
onfocus获取焦点
oninput输入
onchange改变
onsubmit提交
onreset重置
(页面) 事件描述
onload页面加载结束
onscroll滚动
onresize改变大小

获取事件源:
事件源是作为event对象的属性存在的。在W3C规范中,这个属性是 target ;但是 IE8.0 及其以下版本不支持该属性,它使用 srcElement 属性来获取事件源。

<html>
<head>
<title>获取事件源</title>
</head>
<body>
<div id="demo">点击这里</div>
<script type="text/javascript">
 document.getElementById("demo").onclick=function(e){
 var eve = e || window.event;
 var srcNode = eve.target || eve.srcElement; // 兼容所有浏览器
 alert(srcNode);
 }
</script>
</body>
</html>
事件流:

描述的是从页面中接收事件的顺序,也可以理解为事件的传播顺序。

DOM事件流存在的三个阶段

  • 事件捕获阶段
  • 处于目标阶段
  • 事件冒泡阶段

事件捕获(event capturing):当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。

事件冒泡(dubbed bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点。

DOM标准事件流的触发的先后顺序为:先捕获再冒泡,即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。

不同的浏览器对此有着不同的实现,IE10及以下不支持捕获型事件,所以就少了一个事件捕获阶段,IE11、Chrome 、Firefox、Safari等浏览器则同时存在。

target 和 currentTarget

  • target是触发事件的某个具体的对象,只会出现在事件机制的目标阶段,即"谁触发了事件,谁就是target"。
  • currentTarget是绑定了当前事件类型的对象,有可能是目标节点的祖先节点。

阻止事件在冒泡阶段传播

event.stopPropagation //阻止事件在冒泡阶段传播

<!-- 例子结构 -->
<div id="outer">
  <p id="inner"></p>
</div>
/**
 * 点击#inner之后会发生如下过程:
 * outer捕获阶段
 * inner 一
 * inner 二
 * inner 三
 */
const inner = document.querySelector('#inner');
const outer = document.querySelector('#outer');

inner.addEventListener("click", event => {
  console.log("inner 一");
}, false);

inner.addEventListener("click", event => {
  console.log("inner 二");
  event.stopPropagation();
}, false);

inner.addEventListener("click",event => {
  console.log("inner 三");
}, false);

outer.addEventListener("click", event => {
  console.log("outer捕获阶段");
}, false);

outer.addEventListener("click", event => {
  console.log("outer冒泡阶段");
}, false);

如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了event.stopImmediatePropagation()方法,则当前元素剩下的监听函数将不会被执行,并且阻止事件在冒泡阶段传播。

/**
 * 点击#inner之后会发生如下过程:
 * outer捕获阶段
 * inner 一
 * inner 二
 */
const inner = document.querySelector('#inner');
const outer = document.querySelector('#outer');

inner.addEventListener("click", (event) => {
  console.log("inner 一");
}, false);

inner.addEventListener("click", (event) => {
  console.log("inner 二");
  event.stopImmediatePropagation();
}, false);

inner.addEventListener("click",(event) => {
  console.log("inner 三");
}, false);

outer.addEventListener("click", event => {
  console.log("outer捕获阶段");
}, false);

outer.addEventListener("click", event => {
  console.log("outer冒泡阶段");
}, false);
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值