js事件(1)---事件流

事件
事件是由浏览器动作(如浏览器载入文档onload)和用户动作(如点击onclick)触发所产生得人机交互瞬间。

事件流
描述事件从页面到接受处理的流程

事件流感性认知

<!DOCTYPE html>
<html lang="en" id="html" onclick="Ht()">
	<head>
		<meta charset="UTF-8">
		<title>事件流</title>
	</head>
	<body id="body" onclick="Bo()">
		<div id="div" onclick="Di()">
			<button id="button" onclick="Bu()">点我</button>
		</div>
	</body>

	<script>
		function Bu() {console.log("我是button");}

		function Di() {console.log("我是div");}

		function Bo() {console.log("我body");}

		function Ht() {console.log("我是html");}
	</script>

</html>

结果:在这里插入图片描述
这里我只点击了button,但是所有点击事件全部被触发了。感性认识,可能想:因为button包在div,div包在body,body包在html,所以我点击button,也就相当于点击了他们,所以就触发。然而追根述源,只这是DOM事件流模型的其中一种,简称事件冒泡

DOM事件流模型
事件冒泡
由目标元素上所产生的动作为事件触发源,然后事件层层向其父代递交,直至到document节点,期间可能产生连锁的事件触发,如上述代码结果button->div->body->html->document。【微软提出】

事件捕捉
与上述完全相反document->html->body->div->button,下面直接代码演示。【网景提出】
代码:

<!DOCTYPE html>
<html lang="en" id="html">
	<head>
		<meta charset="UTF-8">
		<title>事件流</title>
	</head>
	<body id="body">
		<div id="div">
			<button id="button">点我</button>
		</div>
	</body>
<script>
	var html = document.getElementById("html"),
		body = document.getElementById("body"),
		div = document.getElementById("div"),
		button = document.getElementById("button");

	html.addEventListener("click", Ht, true);

	body.addEventListener("click", Bo, true);

	div.addEventListener("click", Di, true);

	button.addEventListener("click", Bu, true);

	function Bu() {console.log("我是button");}

	function Di() {console.log("我是div");}

	function Bo() {console.log("我body");}

	function Ht() {console.log("我是html");}
</script>

在这里插入图片描述
结果完全相反。
note:

1)、所有现代浏览器都支持事件冒泡,但在具体实现中略有差别:

IE5.5及更早版本中事件冒泡会跳过元素(从body直接跳到document)。

IE9、Firefox、Chrome、和Safari则将事件一直冒泡到window对象。

2)、IE9、Firefox、Chrome、Opera、和Safari都支持事件捕获。尽管DOM标准要求事件应该从document对象开始传播,但这些浏览器都是从window对象开始捕获事件的。

3)、由于老版本浏览器不支持,很少有人使用事件捕获。建议使用事件冒泡。

事件流的三个阶段
事件捕捉阶段:由外部动作触发到传递到目标元素最近的父节点的过程,途中不会接受事件

处于目标元素阶段:从事件传入到目标元素之初,到未接收事件之末的过程。

冒泡阶段:从事件接受处理触发之初,到事件递交document节点之末的过程,途中接受事件

示意图:
在这里插入图片描述

事件代理【利用事件冒泡】
如果一个父节点内含有多个子节点,并且每个子节点都存在同一事件类型(如onclick)。我们可以为其父代设置一个事件处理器(onclick),来避免为其每个子代设置一个事件处理器,降低内存,提高性能。
代码

<!DOCTYPE html>
<html lang="en" id="html">
	<head>
		<meta charset="UTF-8">
		<title>事件流</title>
	</head>
	<body>
		<ul id="ul" onclick="show(event)">
			<li>11</li>
			<li>22</li>
			<li>33</li>
			<li>44</li>
		</ul>
	</body>
	<script>
		function show (e) {
			//事件target属性:返回事件的目标节点(简称触发节点)
			var tagname = e.target;
			if (tagname.nodeName = "li")
			alert(tagname.innerHTML);
		}
		
	</script>
</html>

在这里插入图片描述

事件target属性讲解

如果想要阻止某个子代的事件发生,可以:

<script>
		function show(e) {
			//事件target属性:返回事件的目标节点(简称触发节点)
			var tagname = e.target;
			if (tagname.nodeName = "li") {
				if (tagname.innerHTML == '22')
				    //阻止事件的处理
					e.stopPropagation();
				else
					alert(tagname.innerHTML);
			}
		}
	</script>

菜鸟爬行中…

猜你喜欢

转载自blog.csdn.net/h1234561234561/article/details/88029743
今日推荐