javaScript事件流
事件流:事件从发生到传播结束的过程。
事件流三个阶段:捕获阶段、目标阶段、冒泡阶段。
addEventListener:
EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget
上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element
,Document
和Window
或者任何其他支持事件的对象 (比如 XMLHttpRequest
)。
addEventListener()
的工作原理是将实现EventListener
的函数或对象添加到调用它的EventTarget
上的指定事件类型的事件侦听器列表中。
事件冒泡:从内到外,当父子元素都绑定同样的事件时,触发子元素,父元素也会被触发。
案例:第三个参数为false为表示冒泡
打印结果为:
btn
ps
ls
<!DOCTYPE html> <html> <head> <meta charset:"utf-8"> <title></title> </head> <body> <div class="ls"> <div class="ps"> <button class="btn">按钮</button></button> </div> </div> </body> </html> <script type:"text/javascript"> var btn = document.querySelector(".btn") var ps = document.querySelector(".ps") var ls = document.querySelector(".ls")
btn.addEventListener("click",function(){ console.log("btn") },false) ps.addEventListener("click",function(){ console.log("ps") },false) ls.addEventListener("click",function(){ console.log("ls") },false)</script>
捕获阶段:从外到内,和冒泡相反
案例:第三个参数为true表示冒泡
打印结果:
ls
ps
btn
<!DOCTYPE html> <html> <head> <meta charset:"utf-8"> <title></title> </head> <body> <div class="ls"> <div class="ps"> <button class="btn">按钮</button></button> </div> </div> </body> </html> <script type:"text/javascript"> var btn = document.querySelector(".btn") var ps = document.querySelector(".ps") var ls = document.querySelector(".ls") btn.addEventListener("click",function(){ console.log("btn") },true) ps.addEventListener("click",function(){ console.log("ps") },true) ls.addEventListener("click",function(){ console.log("ls") },true)</script>
阻止捕获和冒泡:event.stopPropagation()
兼容性:
Event.cancelBubble
属性是 Event.stopPropagation()
的一个曾用名。在从事件处理程序返回之前将其值设置为true可阻止事件的传播。
注意:不能阻止默认事件发生,例如:链接。可使用 event.preventDefault()
案例:
结果打印为:
btn
ps
<!DOCTYPE html> <html> <head> <meta charset:"utf-8"> <title></title> </head> <body> <div class="ls"> <div class="ps"> <button class="btn">按钮</button></button> </div> </div> </body> </html> <script type:"text/javascript"> var btn = document.querySelector(".btn") var ps = document.querySelector(".ps") var ls = document.querySelector(".ls") btn.addEventListener("click",function(){ console.log("btn") },false) ps.addEventListener("click",function(){ console.log("ps") event.stopPropagation() // event.cancelBubble = true },false) ls.addEventListener("click",function(){ console.log("ls") },false) </script>
并不是所有的事件都有冒泡,例如:
onblur
onfocus
onmouseenter
onmouseleave
input绑定事件执行顺序
onmouseenter—onfocus—onmousedown—onmouseup—onclick—onmouseleave
<!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> </head> <body> <input type="text" id="text"> </body> <script> const text = document.getElementById('text'); text.onclick = function (e) { console.log('onclick') } text.onfocus = function (e) { console.log('onfocus') } text.onmousedown = function (e) { console.log('onmousedown') } text.onmouseenter = function (e) { console.log('onmouseenter') } text.onmouseup = function (e) { console.log('onmouseup') }
</script> </html>
onmouseover 和 onmouseenter 区别
这两者都是移入的时候触发,但是 onmouseover
会触发多次,而 onmouseenter
只在进去的时候才触发。
案例:鼠标从下到上移动
<!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> </head> <style> .div{ width: 200px; height: 200px; border: 1px solid #ccc; display: flex; flex-direction: column; justify-content: space-around; align-items: center; } .div div{ width: 100px; height: 60px; border: 1px solid #ccc; } </style> <body> <div class="div"> <div class="div1"></div> <div class="div2"></div> </div> </body> <script> document.querySelector(".div").onmouseover = function(){ console.log("onmouseover") } document.querySelector(".div").onmouseenter = function(){ console.log("onmouseenter") } </script> </html>