事件
HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。
事件流
事件流描述的就是从页面中接收事件的顺序。而早期的IE和Netscape提出了完全相反的事件流概念,IE事件流是事件冒泡,而Netscape的事件流就是事件捕获。
事件流类别
事件冒泡
即从下至上,从目标触发的元素逐级向上传播,直到window对象。
事件捕获
即从上至下,从document逐级向下传播到目标元素。
后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是上述二者的结合。
DOM2级事件规定的事件流包括三个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
DOM事件级别
分为四个级别
DOM0:不是W3C规范。
DOM1:开始是W3C规范。专注于HTML文档和XML文档。
DOM2:对DOM1增加了样式表对象模型
DOM3:对DOM2增加了内容模型 (DTD 、Schemas) 和文档验证。
DOM0级
DOM0级事件具有极好的跨浏览器优势,会以最快的速度绑定。绑定方式有如下两种
行内绑定(内联模型)
将函数名直接作为html标签中属性的属性值。
<div onclick="btnClick()">按钮</div> <script> function btnClick(){ console.log("hello"); } </script>
动态绑定(脚本模型)
通过在JS中选中某个节点,然后给节点添加onclick属性
<div id="btn">按钮</div> <script> var btn = document.getElementById("btn"); btn.onclick = function(){ console.log("点击"); } </script>
注意"htmlcode">
<div id="btn">按钮</div> <script> var btn=document.getElementById("btn"); btn.addEventListener("click",hello,false); btn.addEventListener("click",helloagain,false); function hello(){ console.log("hello"); } function helloagain(){ console.log("hello again"); } </script> // 点击后结果: // hello // hello again
注意"htmlcode">
<div id="btn">点击</div> <script> var btn=document.getElementById("btn"); btn.addEventListener("click",hello,false); btn.addEventListener("click",hello,false); function hello(){ console.log("hello"); } </script> // 点击后结果: // hello
DOM3级
对DOM2增加了内容模型 (DTD 、Schemas) 和文档验证。定义了一些新的事件,比如键盘事件,还可以自定义事件。
自定义事件
自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。要创建的自定义事件可以由createEvent("CustomEvent"); 返回的对象有一个initCustomEvent()方法接收如下四个参数。
- type:字符串,触发的事件类型,自定义。例如 “keyDown”,“selectedChange”;
- bubble(布尔值):标示事件是否应该冒泡;
- cancelable(布尔值):标示事件是否可以取消;
- detail(对象):任意值,保存在event对象的detail属性中;
可以像分配其他事件一样在DOM中分派创建的自定义事件对象。如:
var div = document.getElementById("myDiv"); EventUtil.addEventHandler(div,"myEvent", function () { alert("div myEvent!"); }); EventUtil.addEventHandler(document,"myEvent",function(){ alert("document myEvent!"); }); if(document.implementation.hasFeature("CustomEvents","3.0")){ var e = document.createEvent("CustomEvent"); e.initCustomEvent("myEvent",true,false,"hello world!"); div.dispatchEvent(e); }
这个例子中创建了一个冒泡事件“myEvent”。而event.detail的值被设置成了一个简单的字符串,然后在div和document上侦听该事件,因为在initCustomEvent中设置了事件冒泡。所以当div激发该事件时,浏览器会将该事件冒泡到document。
阻止冒泡
stopPropagation函数
btn.addEventListener('click',function(ev){ ev.stopPropagation(); console.log('阻止冒泡') }, false)
事件委托(事件代理)
原理
如果有多个DOM节点需要监听事件的情况下,给每个DOM绑定监听函数,会极大的影响页面的性能,因为我们通过事件委托来进行优化,事件委托利用的就是冒泡的原理。
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <script> var li_list = document.getElementsByTagName('li') for(let index = 0;index<li_list.length;index++){ li_list[index].addEventListener('click', function(ev){ console.log(ev.currentTarget.innerHTML) }) } </script>
正常情况我们给每一个li都会绑定一个事件,但是如果这时候li是动态渲染的,数据又特别大的时候,每次渲染后(有新增的情况)我们还需要重新来绑定,又繁琐又耗性能;这时候我们可以将绑定事件委托到li的父级元素,即ul。
var ul_dom = document.getElementsByTagName('ul') ul_dom[0].addEventListener('click', function(ev){ console.log(ev.target.innerHTML) })
target和currentTarget区别:
- target返回触发事件的元素,不一定是绑定事件的元素
- currentTarget返回的是绑定事件的元素
优点
- 提高性能: 每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。
- 动态监听: 使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。
以上就是详解JavaScript 事件流的详细内容,更多关于JavaScript 事件流的资料请关注其它相关文章!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]