40 DOM事件与事件委托

1 捕获和冒泡

2002年,W3C发布标准

文档名为DOM Level 2 Events Specification

规定浏览器应该同时支持两种调用顺序

首先按 爷爷 => 爸爸 => 儿子 顺序看有没有函数监听

然后按 儿子 => 爸爸 => 爷爷 顺序看有没有函数监听

有监听函数就调用,并提供事件信息,没有就跳过

事件绑定API

IE5 *:baba.attachEvent('onclick',fn) //冒泡

网景:baba.addEventListener('click',fn) //捕获

W3C:baba.addEventListener('click',fn,boolean)   ==>>>> W3C标准

如果boolean不传值或者为falsy

就让fn走冒泡,即当浏览器在冒泡阶段发现baba 有fn监听函数,就会调用fn ,并提供事件信息

如果boolean为true

就让fn走捕获,即当前浏览器在捕获阶段发现baba有fn监听函数,就会调用fn,并提供事件信息

术语

从外向内找监听函数,叫事件捕获

从内向外找监听函数,叫事件冒泡   

实例链接  => 先捕获  后冒泡

2  target VS currentTarget

e.target - 用户操作的元素

e.currentTarget - 程序员监听的元素

this 是e.currentTarget,不推荐使用(因为用this你不知道你获取的是target 还是currentTarget )  =>>>>  在事件监听中 不推荐使用this

举个例子

div > span{文字}   当用户点击文字 =>>>>看下面理解

e.target就是span

e.currentTarget就是div

一个特例

背景

只有一个div被监听(不考虑父子同时被监听)

fn分别在捕获阶段和冒泡阶段监听click事件

用户点击的元素就是开发者监听的

代码

div.addEventLisenter('click',f1)   两行中 谁放在前面一行(第一行)谁就先执行 (也就是谁先监听谁先执行)

div.addEventLisenter('click',fn,true)

请问,f1先执行还是f2先执行? =>>>>>>>>>   谁先监听谁先执行

如果把两行调换位置后,请问哪个先执行? =>>>>>>>>  谁先监听谁先执行

3 取消冒泡  

    =>>捕获不可取消,但冒泡可以

e.stopPropagetion() 可中断冒泡,浏览器不再向上走

一般用于封装某些独立的组件

4 不可阻止默认动作

    有些事件不能阻止默认动作

MDN 搜索srcoll event,看到Bubbles 和 Cancelable

Bubbles的意思是该事件是否冒泡,所有冒泡都可取消

Cancelable的意思是开发者是否可以阻止默认事件

Cancelable与冒泡无关

推荐看mnd英文版 中文版本内容不全

5 如何阻止滚动

scroll事件不可阻止默认动作

阻止scroll默认动作没用,因先有滚动才有滚动事件

要阻止滚动,可阻止wheel和touchstart的默认动作

注意你需要找准滚动条所有的元素

但是滚动条还能用,可用css让滚动条width:0

2 --来自几人谷教学图

css也行

使用overflow:hidden可以直接取消滚动条

但此时JS依然可以修改scrollTop

6 自定义事件

各种默认事件链接

以下代码是如何自定义一个事件

const button = document.querySelector('.button1')

button.addEventListener('click',()=>{    

const event = new CustomEvent('lulu',{        

detail{name:'frank',age:'18'},        //设置内容

bubbles:true , //是否取消冒泡        

composed:false //是否阻止冒泡 不阻止

})    

div1.dispatchEvent(event)})div.addEventListener('lulu',(e)=>{     

//div1为div标签id=div1

console.log(e.detail)

})


自定义事件

7 事件委托

事件委托:我委托一个人 帮我干本来我该干的事情

     ====>>>>> 小记 案例用到的一些方法

1  js字母大小写转换方法

        转换成大写:toUpperCase()

        转换成小写:toLowerCase()

2  tagName  获取标签名

    e.target.tagName  获取用户点击的标签名

    e.currentTarget.tagName  获取程序员点击事件的标签名

3 e.target.dataset.id   具体可看下图1

      获取html内容 data-id='1' 里面的1 <div data-id='1'>21313</div>

4 e.target.textContent 

    获取当前用户操作标签点击按钮的内容21313 <div data-id='1'>21313</div>

图1

第一小节 100个按钮 怎么省内存监听

实例代码

box.addEventListener('click',(e)=>{   

    const t = e.target    // console.log(t)    

    if(t.tagName.toLowerCase() === 'button'){      

        console.log('button被点击了,我的内容是:'+ t.textContent)    //获取button上面展示的内容 如下图2

        console.log('被点击了 ,我获取的内容是 标签上的data-id= ' + t.dataset.id) //图3图解

     }      

 })    


事件委托 图2


事件委托图3

第二小节 怎么监听暂时不存在(后面动态生成或者是setTimeout(1000s)执行)的元素

上代码

// 获取暂时不存在的元素

setTimeout(()=>{    

const button= document.createElement('button')   

 button.textContent = '我是button内容'    

// console.log(button)        

box.appendChild(button) //注意点 写的时候写错了 前面是父元素 后面是要添加的子元素

},1000)

box.addEventListener('click',(e)=>{    

const t = e.target    

if(t.tagName.toLowerCase()==='button'){             

console.log('被点击')    

}})   

第三小节 封装事件委托

要求:

写出这样一个函数on('click','#testDiv','li',fn)

当用户点击#testDiv里面的li远不时,调用fn函数

要求用到事件委托

代码

setTimeout(()=>{   

 const button = document.createElement('button')    

button.textContent = '我是动态1000s后button里面的内容'    

box.appendChild(button)},1000)

on('click','#box','button',()=>{    

console.log('元素被点击了')})

function on(eventType,element,selector,fn){   

 if(!(element instanceof Element)){ //   判断一个元素是不是真正的元素 判断它是不是对象也可以用它  instanceof Object   判断数组 instanof Array

element = document.querySelector(element)   

 }    

element.addEventListener(eventType,(e)=>{     

const t = e.target       

 if(t.matches(selector)){     //matches 判断它是不是一个选择器

       fn(e)       

 }        

 } 

)}        


封装委托事件图解

代码二:高级版 (给button里面的span加点击 代码一 不能实现点击)

setTimeout(()=>{    

const button = document.createElement('button')    

const span = document.createElement('span')    

span.textContent = '我是动态1000s后span里面的内容'    

box.appendChild(button)   

 button.appendChild(span)},1000)

on('click','#box','button',()=>{     

console.log('button 被点击了')})

function on(eventType,element,selector,fn){    

if(!(element instanceof Element)){            

 element = document.querySelector(element)    }    

element.addEventListener(eventType,(e)=>{       

 let t = e.target        

while(!t.matches(selector)){            

if(element === t){             

t = null               

break            

}             

t = t.parentNode               

 }       

 t && fn.call(t,e,t)   

 })    

 return element      

}     

JS支持事件吗?

答:

支持 也不支持   以上案例写的DOM事件不属于JS功能,术语浏览器提供的DOM功能

JS只是调用了DOM提供的addEventListener()而已

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容