1. <div class="爷爷">
  2. <div class="爸爸">
  3. <div class="儿子">
  4. 文字
  5. </div>
  6. </div>
  7. </div>

给三个div分别添加事件监听fnYe/fnBa/fnEr
问:上述代码,点击文字,算点击了谁
答:都算

调用顺序:

  • 首先从外向内按爷爷=>爸爸=>儿子顺序看有没有函数监听
  • 然后从内向外按儿子=>爸爸=>爷爷顺序看有没有函数监听
  • 事件捕获:从外向内找监听函数,叫事件捕获
  • 事件冒泡:从内向外找监听函数,叫事件冒泡
  • 如果事件函数放在捕获阶段,则函数在捕获阶段会被找到然后调用
  • 如果事件函数放在冒泡阶段,则经历捕获阶段时没有找到事件函数,然后开始冒泡阶段,在这个阶段事件函数被找到,最后调用

特例:监听元素===操作元素的事件调用顺序:哪个事件在先,哪个事件就先被监听

添加事件的方法:

target.addEventListener(‘click’,fn,bool)
如果bool不传或为fasly就将事件函数放置在冒泡阶段
如果bool为true,就将事件函数放置在捕获阶段

target 和 currentTarget 的区别

  • e.target:是用户操作的元素(触发事件元素)
  • e.currentTarget是程序员监听的元素 (绑定事件元素)

打断冒泡过程

函数:e.stopPropagation()
但有的事件比较特殊,不能取消。如:scroll

禁止页面滚动

1、阻止滚轮效果

x.addEventListener(“wheel”,(e)=>{
e.preventDefault()
})

2、阻止触屏效果

x.addEventListener(“touchstartl”,(e)=>{
e.preventDefault()
})

3、除去页面滚动条(css处添加)

::-webkit-scrollbar {
width : 0 !important
}

自定义事件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JS Bin</title>
  6. </head>
  7. <body>
  8. <div id=div1>
  9. <button id=button1>点击触发 Bruce 事件
  10. </button>
  11. </div>
  12. </body>
  13. </html>
  1. button1.addEventListener('click', ()=>{
  2. const event = new CustomEvent("Bruce", {"detail":{name:'Bruce', age: 18}})
  3. button1.dispatchEvent(event)
  4. })
  5. button1.addEventListener('Bruce', (e)=>{
  6. console.log('Bruce')
  7. console.log(e.detail)
  8. })

事件委托:

场景一:

需要给100个按钮添加点击事件,咋办?
答: 监听这100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个

image.png

场景二:

需要监听当前还不存在的元素的点击事件,咋办?
答:监听祖先即可,等冒泡的时候判断target是不是想要监听的元素即可
image.png

事件委托的优点:

  1. 省监听数(内存)
  2. 可以监听动态元素

封装事件委托:

要求:写出一个函数on(‘click’,’#testDiv’,’button’,fn),当用户点击#testDiv里的button元素时,调用fn函数,要求用到事件委托
答案: 通过递归判断e.target的祖先是否有button元素,且li元素依旧是在#testDiv里面的
image.png

  1. const delegate = function(eventType,element,selector,fn){
  2. element.addEventListener(eventType,e=>{
  3. let el = e.target
  4. while(!el.matches(selector)){
  5. if(element===el){
  6. el = null
  7. break
  8. }
  9. el = el.parentNode
  10. }
  11. el&&fn.call(el,e,el)
  12. })
  13. return element
  14. }

注:这里讲到事件是DOM事件,是DOM的功能,而不是JS的功能,JS只是调用了DOM提供的addEventListener而已。