javascript中的addEventListener(事件名,回调,布尔)
其中第三个参数默认为false-事件冒泡,true为事件捕获
二者区别:
- 事件冒泡:目标元素事件先触发,然后父元素事件触发
- 事件捕获:父元素事件先触发,然后目标元素事件触发
1 <body id="body"> 2 <div id="div1"> 3 <a href="#">a1</a> 4 <a href="#">a2</a> 5 <a href="#">a3</a> 6 <a href="#">a4</a> 7 <button id="btn1">点击添加一个a标签</button> 8 </div> 9 </body> 10 <script> 11 //通用绑定事件 12 function bindEvent(elem, type, fn) { 13 elem.addEventListener(type, fn) 14 } 15 16 //事件冒泡 17 const div1 = document.getElementById("div1") 18 bindEvent(div1, 'click', event=>{ //事件冒泡,如果你点击是button或者a 则div1绑定的回调也会触发 19 console.log(event.target) 20 alert('这是冒泡') 21 }) 22 const body = document.getElementById("body") 23 bindEvent(body, 'click', event=>{ //事件冒泡,如果你点击是button或者a 则body绑定的回调也会触发 24 console.log(event.target) 25 alert('这是body') 26 }) 27 </script>
事件委托是利用事件冒泡原理,把事件监听绑定在元素的父级上。当元素被点击时,父级上绑定的点击事件就会被触发,事件触发函数里通过判断 e.target 上的 data-name 或 class 等标识来执行不同的逻辑。
优点:可以减少浏览器内存占用,提高代码整洁度
<body id="body"> <div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <a href="#">a3</a> <a href="#">a4</a> <button id="btn1">点击添加一个a标签</button> </div> </body> <script> //通用绑定事件 function bindEvent(elem, type, fn) { elem.addEventListener(type, fn) } //事件代理 const div1 = document.getElementById("div1") bindEvent(div1, 'click', event=>{ //事件冒泡,可以指定父元素委托某个子元素触发父元素绑定的回调 event.preventDefault(); let target = event.target if(target.nodeName=='A') { console.log('这是div') } }) </script>
阻止事件冒泡和默认事件
event.preventDefault()可以阻止如a链接等默认行为
event.stopPropagation()可以阻止事件继续冒泡
手写一个事件函数
1 //通用绑定事件 2 function bindEvent(elem, type, selector, fn) { 3 //如果fn为null则证明这是普通事件 4 if(fn == null) { 5 fn = selector 6 selector = null 7 } 8 elem.addEventListener(type, event =>{ 9 const target = event.target 10 //如果selector存在证明他是事件委托 11 if(selector) { 12 if(target.matches(selector)) { 13 fn.call(target, event) 14 } 15 }else { 16 fn.call(target, event) 17 } 18 }) 19 }