第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 面试题7:Js事件流 事件冒泡(IE事件流)

面试题7:Js事件流 事件冒泡(IE事件流)

时间:2022-02-05 02:46:39

相关推荐

面试题7:Js事件流 事件冒泡(IE事件流)

事件流

在第四代 Web 浏览器(IE4 和 Netscape Communicator 4)开始开发时,开发团队碰到了一个有意思的问题:页面哪个部分拥有特定的事件呢?要理解这个问题,可以在一张纸上画几个同心圆。把手指放到圆心上,则手指不仅是在一个圆圈里,而且是在所有的圆圈里。两家浏览器的开发团队都是以同样的方式看待浏览器事件的。当你点击一个按钮时,实际上不光点击了这个按钮,还点击了它的容器以及整个页面。

事件流描述了页面接收事件的顺序。结果非常有意思,IE 和 Netscape 开发团队提出了几乎完全相反的事件流方案。IE 将支持事件冒泡流,而 Netscape Communicator 将支持事件捕获流。

事件冒泡(IE事件流)

IE 事件流被称为事件冒泡,这是因为事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。

面试官:什么是事件冒泡

例如:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{color: white;font-size: 20px;}#outer{width: 300px;height: 300px;background-color: red;}#center{width: 200px;height: 200px;background-color: blue;}#inner{width: 100px;height: 100px;background-color: green;}</style></head><body><div id="outer">outer<div id="center">center<div id="inner">inner</div></div></div><script>var inner = document.getElementById('inner');var center = document.getElementById('center');var outer = document.getElementById('outer');// 当我们只有一个inner点击方法的时候 我们发现想要实现的效果和我们预期的一样inner.onclick = function () {console.log('我是inner点击的');}// 但是当我们给inner的父元素和祖先元素也添加点击事件时 一点击inner 所有祖先元素的事件都会被触发,这就是事件冒泡现象center.onclick = function () {console.log('我是center点击的');}outer.onclick = function () {console.log('我是outer点击的');}</script></body></html>

效果:

点击inner之后会输出inner,和后面父级的center、outer

在点击页面中的id为inner的div元素,click事件会以如下顺序发生

由内向外

div#inner

div#center

div#outer

body

html

document

也就是说,div#inner元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。

所有现代浏览器都支持事件冒泡,只是在实现方式上会有一些变化。IE5.5及早期版本会跳过html元素(从body直接到 document)。现代浏览器中的事件会一直冒泡到 window 对象。

阻止事件冒泡

使用阻止事件冒泡之前,先要知道DOM事件默认提供的一个对象,HTML DOM Event对象。

Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。

事件通常与函数结合使用,函数不会在事件发生前被执行!

event.stopPropagation()

直接在对应方法中使用event.stopPropagation()便可阻止事件冒泡。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{color: white;font-size: 20px;}#outer{width: 300px;height: 300px;background-color: red;}#center{width: 200px;height: 200px;background-color: blue;}#inner{width: 100px;height: 100px;background-color: green;}</style></head><body><div id="outer">outer<div id="center">center<div id="inner">inner</div></div></div><script>var inner = document.getElementById('inner');var center = document.getElementById('center');var outer = document.getElementById('outer');// 当我们只有一个inner点击方法的时候 我们发现想要实现的效果和我们预期的一样inner.onclick = function (event) {console.log('我是inner点击的');//阻止事件冒泡event.stopPropagation();}// 但是当我们给inner的父元素和祖先元素也添加点击事件时 一点击inner 所有祖先元素的事件都会被触发,这就是事件冒泡现象center.onclick = function () {console.log('我是center点击的');}outer.onclick = function () {console.log('我是outer点击的');}</script></body></html>

效果:

点击inner之后只会输出inner,而后面父级的不会输出center、outer了

注意:如果点击方法时需要同时传递其他参数和event,直接传递event这个单词即可

onclick="test(123,event)"

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{color: white;font-size: 20px;}#outer{width: 300px;height: 300px;background-color: red;}#center{width: 200px;height: 200px;background-color: blue;}#inner{width: 100px;height: 100px;background-color: green;}</style></head><body><div id="outer">outer<div id="center">center<!-- 第一种:匿名函数 ,整体性好--><!-- <div id="inner" onclick="myFun(123,event)">inner</div> --><!-- 第二种:有名函数 --><div id="inner" onclick="myFun(123,event)">inner</div></div></div><script>var inner = document.getElementById('inner');var center = document.getElementById('center');var outer = document.getElementById('outer');/*// 当我们只有一个inner点击方法的时候 我们发现想要实现的效果和我们预期的一样//第一种:匿名函数inner.onclick = function (event) {console.log('我是inner点击的');//阻止事件冒泡event.stopPropagation();} */// 第二种:有名函数var myFun=function(a,event){console.log(a,event);}// 但是当我们给inner的父元素和祖先元素也添加点击事件时 一点击inner 所有祖先元素的事件都会被触发,这就是事件冒泡现象center.onclick = function () {console.log('我是center点击的');}outer.onclick = function () {console.log('我是outer点击的');}</script></body></html>

效果:点击inner之后只会输出inner,而后面父级的不会输出center、outer了

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。