JavaScript复习——04 事件

  • JavaScript复习——04 事件已关闭评论
  • 158 次浏览
  • A+
所属分类:Web前端
摘要

事件对象是由浏览器在外面触发事件的时候创建的,这个对象封装了各种事件相关的各种信息


事件对象

事件对象是由浏览器在外面触发事件的时候创建的,这个对象封装了各种事件相关的各种信息

例如:

  1. 鼠标的位置
  2. 键盘的按键

浏览器创建事件对象后,会将事件对象作为响应参数传递
在DOM类型中有多种不同类型的事件对象,但是他们都一个祖先Event

  1. event.clientX:获取鼠标的X轴坐标
  2. event.clientY:获取鼠标的Y轴坐标
  3. event.target:表示触发事件的对象
  4. event.currentTarget:绑定事件的对象
<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <title>DOM</title>       <style>           .box1 {               width:300px;               height:300px;               background-color: #bfa;           }       </style>   </head>   <body>       <div id="box1" class="box1">           <div id="box2">                          </div>       </div>     <script>         const box1 = document.getElementById("box1")         const box2 = document.getElementById("box2")         box1.onclick = function(event) { 			console.log(event.target)             console.log(this)         }          box2.onclick = function(event) { 			alert('我是box2')         }      </script>   </body> </html> 

事件冒泡

事件冒泡:当我们的元素上某个事件被触发(内部元素不一定要绑定事件)后,其祖先元素的相同事件也会被触发,冒泡大大的简化了我们代码的编写,但是在某些场景下,我们有时也不希望冒泡

  1. event.stopPropagation():取消事件传导
  2. event.preventDefault():取消事件的默认行为
<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <title>DOM</title>       <style>           .box1 {               width:300px;               height:300px;               background-color: #bfa;           }           #box {               width:100px;               height:100px;               background-color: orange;           }       </style>   </head>   <body>       <div id="box1" class="box1">           <div id="box2">                          </div>       </div>     <script>         const box1 = document.getElementById("box1")         const box2 = document.getElementById("box2")         box1.onclick = function(event) { 			console.log(event.target)             console.log(this)         }          box2.onclick = function(event) {             // 停止box2点击事件的传导             event.stopPropagation() 			alert('我是box2')         }      </script>   </body> </html> 

冒泡为什么有利

当我们需要所有元素都有一个共有的事件时,我们如果没有冒泡就需要一个个给他们添加事件
如果我们有冒泡,就只需要给它们的共同祖先元素添加一个事件就可以,这就是冒泡的好处
因为我们自己元素点击之后,事件会向上冒泡,所以父级元素的处理器也会感知到

事件的委托

我们希望,只绑定一次事件,就可以让所有的超链接和未来新添加的都具有这些事件

思路:我们可以将事件统一绑定document,这样点击超链接之后,由于事件的冒泡会导致document的事件被触发,这样就只绑定了一次,所有的超链接都会具有这些事件
但是这也带来了一个问题,会让除了超链接外的元素也触发事件

委托:就是本该绑定给多个对象的事件,绑定给它们的共同祖先元素,这样就可以降低我们代码的复杂度

<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <title>DOM</title>   </head>   <body>       <button type="button" id="btn">           点我一下       </button>       <ul id="list">           <li><a href="javascript:;">链接1</a></li>           <li><a href="javascript:;">链接2</a></li>           <li><a href="javascript:;">链接3</a></li>           <li><a href="javascript:;">链接4</a></li>       </ul>     <script>         const links = document.links;         const list = document.getElementById('list')         const btn = document.getElementById('btn')         for(let i = 0; i < links.length; i++) {             links[i].addEventListener('click',(event)=>{                 alert(event.target.textContent)             })         }         // 点击按钮之后新添加一个li         /*         	我们新添加的链接并不会绑定事件         */         btn.addEventListener('click',()=>{             list.insertAdjancentHTML("beforeend","<li><a href="javascript:;">新链接</a><</li>")         })     </script>   </body> </html> 

处理委托带来的问题

我们之前也说了问题的带来的问题,我们在给共有父元素绑定事件的时候,只要是子元素都有可能触发事件,那么我们如果要选择对应的子元素触发事件呢?

可以用以下的方式来解决

<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <title>DOM</title>   </head>   <body>       <button type="button" id="btn">           点我一下       </button>       <ul id="list">           <li><a href="javascript:;">链接1</a></li>           <li><a href="javascript:;">链接2</a></li>           <li><a href="javascript:;">链接3</a></li>           <li><a href="javascript:;">链接4</a></li>       </ul>     <script>                const list = document.getElementById('list')         const links = list.getElementByTagName('li');         const btn = document.getElementById('btn')                 document.addEventListener("click",(event)=>{             if([...links].includes(event.target)){ 				alert('超链接事件对象触发了')             }          })         // 点击按钮之后新添加一个li         /*         	我们新添加的链接并不会绑定事件         */         btn.addEventListener('click',()=>{             list.insertAdjancentHTML("beforeend","<li><a href="javascript:;">新链接</a><</li>")         })     </script>   </body> </html> 

这上面的代码必须是li才能触发事件,要不然是不能触发事件的

事件的捕获

在DOM中,事件的传播分为三个阶段

  1. 捕获阶段
    • 事件的捕获指的是我们的事件从外向内传导
    • 由祖先元素向目标元素进行事件的捕获
  2. 目标阶段(触发事件的对象)
  3. 冒泡阶段
    • 由目标元素想祖先元素进行冒泡从内向外传导

如果我们希望在捕获阶段触发事件,那么我们就需要将addEventListener()的第三个参数设置为true

注意:我们一般不希望在捕获阶段触发事件,设置了捕获事件,冒泡就会失效

  1. evnet.eventPhase:事件触发的时机
    1. 0:表示没有触发事件
    2. 1:是捕获阶段
    3. 2:表示为目标阶段
    4. 3:表示冒泡阶段

<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <title>DOM</title>       <style>          #box1 { 			width:300px;             height:300px;             background-color:skyblue;           }          #box2 { 			width:200px;             height:200px;             background-color:orange;           }           #box2 { 			width:100px;             height:100px;             background-color:tomato;           }       </style>   </head>   <body>       <div id="box1">           <div id="box2">           	 <div id="box3">          	  	 </div>        	  </div>           </div>       <script>           const box1 = document.getElemenetById("box1")           const box2 = document.getElemenetById("box2")           const box3 = document.getElemenetById("box3")                      box1.addEventListener("click",(event)=>{               alert(1)           },true)           box2.addEventListener("click",(event)=>{               alert(2)           },true)           box3.addEventListener("click",(event)=>{               alert(3)           },true)       </script>   </body> </html>