事件冒泡:
子元素嵌套在父元素内部,点击子元素的时候一定同时表示点击了父元素,这个时候,先触发子元素的事件处理器,然后再触发父元素的事件处理器,如果父元素的父元素还有处理器,就一直向上触发,一直到 html > document 元素。就像鱼吐泡泡一样,从水下向水面走,每向上走一层就会查看这一层有没有事件处理器,如果有的话就会触发,如果没有的话就继续向上寻找,直到顶层的html > document ,才结束寻找事件。
事件捕获:
事件捕获则和事件冒泡正好相反,点击的时候从 window > document > html > body > 往下找,如果父级元素有事件处理器就先触发父级元素的事件处理器,再向下一层,如果子级元素有的话就触发子级元素的事件处理器,直到这个点击位置的最底层,也就是我们通常所说的 target。事件捕获就好像一块石头从水面向水下沉一样,如果这一层有事件处理器,就触发,没有就继续向下沉,到下层再查看是否有事件处理器,有的话就触发,没有的话继续向下,一直到最底层,这个石头就停止了。
理论说完了 我们测试下说个小案例吧。
HTML结构
<div id="parent"> <div id="child" class="child"></div> </div>
下来js绑定冒泡事件
document.getElementById("parent").addEventListener("click",function(e){ alert("parent事件被触发,"+this.id); }) document.getElementById("child").addEventListener("click",function(e){ alert("child事件被触发,"+this.id) })
结果:
child事件被触发,child
parent事件被触发,parent
结论:先child,然后parent。事件的触发顺序自内向外,这就是事件冒泡。
下来我们测试捕获 现在改变第三个参数的值为true
document.getElementById("parent").addEventListener("click",function(e){ alert("parent事件被触发,"+e.target.id); },true) document.getElementById("child").addEventListener("click",function(e){ alert("child事件被触发,"+e.target.id) },true)
结果:
parent事件被触发,parent
child事件被触发,child
结论:先parent,然后child。事件触发顺序变更为自外向内,这就是事件捕获。
捕获实际中应用比较少~
===============一条朴素的分割线====================
通过事件冒泡做的留言本
来上代码可以预览哦。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>7.11 留言板-大灰狼</title> <style type="text/css"> *{margin: 0;padding: 0;} body{ background:#000000 url(https://inews.gtimg.com/newsapp_match/0/49787475/0) no-repeat; background-size:100%; color:green; position: relative;} .guestbook{width: 800px; min-width: 800px; font-family: "微软雅黑"; font-weight: bold; position: fixed; left: 10%; bottom: 15px;} #list{list-style: none;} #list li{background: skyblue; opacity: 0.6; border:1px solid slateblue; border-radius: 5px; min-heightheight: 30px; margin: 10px 0; padding: 5px;} #list li button{float: right; background:darkcyan; color: #ffffff; border: 0; padding: 3px; border-radius: 5px; } #name, #message{border-radius: 8px; border: 0;line-height: 26px;margin: 10px; padding: 6px;} #message{width: 300px;} </style> </head> <body> <div class="guestbook"> <div class="message-list"> <ul id="list"> </ul> </div> <div class="name"> <label for="name">您的称呼:</label> <input type="text" name="name" id="name" value="" /> </div> <div class="ms"> <label for="message">发表留言:</label> <input type="text" name="message" id="message" value="" placeholder="在这里输入留言按回车即可!" autofocus/> </div> </div> <script type="text/javascript"> //获取消息框input输入框 var message=document.getElementById("message"); //准备插入子元素的 留言列表 var list=document.getElementById("list"); //产生一个随机数 var rnum=Math.round(Math.random()*10); document.getElementById("name").value="游客"+rnum; //给input输入框添加事件监听 键盘事件 冒泡 message.addEventListener('keypress',addMessage,false); //addMessage事件方法 function addMessage (ev) { //事件方法中有一个默认的参数 就是事件对象:ev,evt,event 任选一个都一样 //使用ev.key 可以获取到 某一个按键的对应值 //发言昵称 var names=document.getElementById("name").value; //发言时间 var addtime=new Date().toLocaleString(); //console.log(ev.key); //当按下回车进行操作 并且不等于空 if(ev.key==="Enter" && message.value!="" && names.value!=""){ //要把input插入到留言列表就先要把input的文本放到一个元素比如li //所以要先创建li元素 var liTemp=document.createElement("li"); //创建的li是空的 给里面插入input输入的文本 liTemp.innerHTML=names+' : '+message.value+ ' --发表于:' +addtime +" <button clss='del'>删除</button>"; //留言数据已经准备好了 来插入到留言列表里面吧 // list.appendChild(liTemp); //留言升序排列 //我们来做一个判断 进行降序插入留言(最新留言在最上面) if (list.childElementCount===0) { //当ul列表子元素为0个直接插入 list.appendChild(liTemp); } else{ //如果有留言插入到第一条留言前面 //insertBefore(a,b) 有2个参数a插入的元素 b插入的位置 //list.insertBefore(liTemp,list.firstElementChild); //将新发言从前面插入 list.appendChild(liTemp); //将消息从后面插入 } //插入成功后 我们把输入框清空 message.value="" message.value=null; } } //给留言列表的button删除按钮添加监听事件 list.addEventListener('click',messageDel); //messageDel函数 function messageDel (ev) { //currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口。 //是 ul。currentTarget是把事件添加给谁了 // var ul=ev.currentTarget; //是li 。target正在触发事件的元素 // var but=ev.target; //判断点击的是button 还是li if (event.target.nodeName=="BUTTON") { //消息删除弹窗询问 if(confirm("是否确定要删掉?")){ //当前正在出发事件的元素,正在被点击的。 // 当前拿到的是button按钮 我们要删除li 是他的父节点 // console.log(ev.target); // var li=but.parentElement; // console.log(li) //进行删除 ev.currentTarget.removeChild(ev.target.parentElement); } } } </script> </body> </html>
点击 "运行实例" 按钮查看在线实例
也可以通过以下网址 访问小案例 源码注解比较详细
http://www.xdidc.com/test0711/7.11lyb.html