JS事件详解(下)

  • 今天来聊⼀聊事件的执⾏机制

    结合上次跟大家分享的事件基础,如果还没有看过的童鞋,以下是传送门
    【js事件详解】上
    在这里插入图片描述

  • 那么什么是事件的执⾏机制呢?

    思考⼀个问题
    当⼀个⼤盒⼦嵌套⼀个⼩盒⼦的时候,并且两个盒⼦都有点击事件
    你点击⾥⾯的⼩盒⼦,外⾯的⼤盒⼦上的点击事件要不要执⾏?
    在这里插入图片描述

1. 事件的传播

就像上⾯那个图⽚⼀样,我们点击在红⾊盒⼦身上的同时,也是点击在了粉⾊盒⼦上,这个是既定事实,那么两个盒⼦的点击事件都会触发,这个就叫做事件的传播

  1. 当元素触发⼀个事件的时候,其⽗元素也会触发相同的事件,⽗元素的⽗元素也会触发相同的事件,就像上⾯的图⽚⼀样
  2. 点击在红⾊盒⼦上的时候,会触发红⾊盒⼦的点击事件,
  3. 也是点击在了粉⾊的盒⼦上,也会触发粉⾊盒⼦的点击事件,
  4. 也是点击在了 body 上,也会触发 body 的点击事件,
  5. 也是点击在了 html 上,也会触发 html 的点击事件,
  6. 也是点击在了 document 上,也会触发 document 的点击事件,
  7. 也是点击在了 window 上,也会触发 window 的点击事件,
  8. 也就是说,⻚⾯上任何⼀个元素触发事件,都会⼀层⼀层最终导致 window的相同事件触发前提是各层级元素得有注册相同的事件,不然不会触发
  • 在事件传播的过程中,有⼀些需要去注意的点:

      1.只会传播同类事件
      2.只会从点击元素开始按照 html 的结构逐层向上元素的事件会被触发
      3.内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会被触发
    
  • 到现在,我们已经了解了事件的传播,我们再来思考⼀个问题

     -事件确实会从⾃⼰开始,到window的所有相同事件都会触发,是因为我们点在⾃⼰身上,也确实逐层的点在了直⾄window的每⼀个元素身上
     -但是到底是先点在⾃⼰身上,还是先点在了window身上呢?
     -先点在⾃⼰身上,就是先执⾏⾃⼰的事件处理函数,逐层向上最后执⾏window的事件处理函数
     -反之,则是先执⾏ window 的事件处理函数,逐层向下最后执⾏⾃⼰身上的事件处理函数
    

2. 冒泡、捕获、⽬标

  • 我们刚才聊过了,每⼀个事件,都是有可能从⾃⼰到 window ,有可能要执⾏多个同类型事件。
  • 那么这个执⾏的顺序就有⼀些说法了。

⽬标

  • 你是点击在哪个元素身上了,那么这个事件的⽬标就是什么。

冒泡和捕获

在这里插入图片描述在这里插入图片描述事件流

  • 事件流是描述的从⻚⾯接受事件的顺序,当⼏个都具有事件的元素层叠在⼀起的时候,那么你点击其中⼀个元素,并不是只有当前被点击的元素会触发事件,⽽层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。

事件冒泡

  • 就是从事件 ⽬标 的事件处理函数开始,依次向外,直到 window 的事件处理函数触发,也就是从下向上的执⾏事件处理函数

事件捕获

  • 就是从 window 的事件处理函数开始,依次向内,只要事件 ⽬标 的事件处理函数执⾏,也就是从上向下的执⾏事件处理函数

冒泡和捕获的区别

  • 就是在事件的传播中,多个同类型事件处理函数的执⾏顺序不同

3. 阻⽌事件传播(冒泡和捕获)

3.1 事件触发(⽬标)对象及兼容

cancelBubble=true IE写法
stopPropagation() 其他浏览器

在这里插入图片描述
3.2 ⽬标对象/触发对象

事件对象.target || window.event.srcElement;

【注】事件是由谁⽽起。

4. 事件委托

在这里插入图片描述

  • 就是把我要做的事情委托给别⼈来做

  • 因为我们的冒泡机制,点击⼦元素的时候,也会同步触发⽗元素的相同事件

  • 所以我们就可以把⼦元素的事件委托给⽗元素来做

    好处:
    1、节省资源同时减少了dom操作,提⾼性能
    2、对于新添加的元素也会有之前的事件

4.1 事件触发

  • 点击⼦元素的时候,不管⼦元素有没有点击事件,只要⽗元素有点击事件,那么就可以触发⽗元素的点击事件
<script>
	var oUl = docuemnt.querySelector('ul')
	oUl.addEventListener('click', function (e) {
	console.log('我是 ul 的点击事件,我被触发了')
 })
</script>
<body>
	 <ul>
	 	 <li>1</li> 
		 <li>2</li> 
		 <li>3</li>
	</ul> 
</body>

像上⾯⼀段代码,当你点击ul的时候肯定会触发
但是当你点击li的时候,其实也会触发

4.2 target

  • target 这个属性是事件对象⾥⾯的属性,表示你点击的⽬标
  • 当你触发点击事件的时候,==你点击在哪个元素上,target就是哪个元素 ==
  • 这个target也不兼容,在 IE下要使⽤srcElement
<script>
	 var oUl = docuemnt.querySelector('ul')
	 oUl.addEventListener('click', function (e) {
	 e = e || window.event
	 var target = e.target || e.srcElement
	 	console.log(target)
 })
 </script>
<body> 
	<ul>
		<li>1</li> 
		<li>2</li> 
		<li>3</li>
	</ul> 
</body>

上⾯的代码,当你点击ul的时候,target就是ul
当你点击在 li 上⾯的时候,target就是 li

4.3 委托

  • 这个时候,当我们点击 li的时候,也可以触发ul的点事件
  • 并且在事件内部,我们也可以拿到你点击的到底是ul还是li
  • 这个时候,我们就可以把 li 的事件委托给 ul 来做
<script>
		var oUl = docuemnt.querySelector('ul')
		oUl.addEventListener('click', function (e) {
		e = e || window.event
		var target = e.target || e.srcElement
		// 判断你点击的是 li
			if (target.nodeName.toUpperCase === 'LI') {
		// 确定点击的是 li
		// 因为当你点击在 ul 上⾯的时候,nodeName 应该是 'UL'
		// 去做点击 li 的时候该做的事情了
			console.log('我是 li,我被点击了')
		 }
		 })
</script>
<body> 
		<ul>
			<li>1</li> 
			<li>2</li> 
			<li>3</li>
		</ul> 

上⾯的代码,我们就可以把 li 要做的事情委托给 ul 来做

5. 默认⾏为

  • 默认⾏为,就是不⽤我们注册,它⾃⼰就存在的事情
  • ⽐如我们点击⿏标右键的时候,会⾃动弹出⼀个菜单
  • ⽐如我们点击a标签的时候,我们不需要注册点击事件,他⾃⼰就会跳转⻚⾯
  • 这些不需要我们注册就能实现的事情,我们叫做默认事件

5.1 阻⽌默认⾏为

有的时候,我们不希望浏览器执⾏默认事件

  • ⽐如我给 a 标签绑定了⼀个点击事件,我点击你的时候希望你能告诉我你的地址是什么
  • ⽽不是直接跳转链接
  • 那么我们就要把a标签原先的默认事件阻⽌,不让他执⾏默认事件

我们有两个⽅法来阻⽌默认事件

	e.preventDefault() : ⾮ IE 使⽤
	e.returnValue = false :IE 使⽤

我们阻⽌默认事件的时候也要写⼀个兼容的写法

<a href="https://www.baidu.com">点击我试试</a> 
	<script>
		var oA = document.querySelector('a')
		 a.addEventListener('click', function (e) {
		 e = e || window.event
			console.log(this.href)
		 e.preventDefault ? e.preventDefault() : e.returnValue =false;
	 })
</script>

这样写完以后,你点击 a 标签的时候,就不会跳转链接了
⽽是会在控制台打印出 a 标签的 href 属性的值

总结:

  1. 为什么要⽤事件委托?

    	我⻚⾯上本身没有 li
    	我通过代码添加了⼀些 li,但是添加进来的 li 是没有点击事件的
    	我每次动态的操作完 li 以后都要从新给li绑定⼀次点击事件⽐较麻烦
    	这个时候只要委托给 ul 就可以了
    	因为新加进来的 li 也是 ul 的⼦元素,点击的时候也可以触发ul的点击事件
    
  2. 事件委托的书写

    	 元素的事件只能委托给结构⽗级或者再结构⽗级的同样的事件上
    	 li 的点击事件,就不能委托给 ul 的⿏标移⼊事件
    	 li的点击事件,只能委托给 ul 或者在⾼⽗级的点击事件上
    

重点】好了以上就是JS事件详解的所有内容,以后还会对js事件有所补充,感兴趣的朋友们可以点赞关注走一波。

发布了3 篇原创文章 · 获赞 41 · 访问量 4300

猜你喜欢

转载自blog.csdn.net/Oriental_/article/details/104676772