Blogger Information
Blog 36
fans 4
comment 3
visits 31879
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
7.11 事件冒泡与捕获 小案例留言本
大灰狼的博客
Original
1252 people have browsed it

事件冒泡:

子元素嵌套在父元素内部,点击子元素的时候一定同时表示点击了父元素,这个时候,先触发子元素的事件处理器,然后再触发父元素的事件处理器,如果父元素的父元素还有处理器,就一直向上触发,一直到 html > document  元素。就像鱼吐泡泡一样,从水下向水面走,每向上走一层就会查看这一层有没有事件处理器,如果有的话就会触发,如果没有的话就继续向上寻找,直到顶层的html > document ,才结束寻找事件。

1.jpg

 

事件捕获:

事件捕获则和事件冒泡正好相反,点击的时候从 window > document > html > body > 往下找,如果父级元素有事件处理器就先触发父级元素的事件处理器,再向下一层,如果子级元素有的话就触发子级元素的事件处理器,直到这个点击位置的最底层,也就是我们通常所说的 target。事件捕获就好像一块石头从水面向水下沉一样,如果这一层有事件处理器,就触发,没有就继续向下沉,到下层再查看是否有事件处理器,有的话就触发,没有的话继续向下,一直到最底层,这个石头就停止了。

3.jpg

 

 

 

理论说完了 我们测试下说个小案例吧。

 

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。事件触发顺序变更为自外向内,这就是事件捕获。

捕获实际中应用比较少~

 

===============一条朴素的分割线====================

通过事件冒泡做的留言本

0.jpg

来上代码可以预览哦。

实例

<!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>
7.13日进行了更新 发现上一个版本布局兼容有问题。
运行实例 »

点击 "运行实例" 按钮查看在线实例

也可以通过以下网址 访问小案例 源码注解比较详细

 http://www.xdidc.com/test0711/7.11lyb.html 

 

Correction status:qualified

Teacher's comments:捕获和冒泡都是以html为起点或终点,并非body
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post