博客列表 >7.11 事件冒泡与捕获 小案例留言本

7.11 事件冒泡与捕获 小案例留言本

大灰狼的博客
大灰狼的博客原创
2019年07月13日 20:13:101251浏览

事件冒泡:

子元素嵌套在父元素内部,点击子元素的时候一定同时表示点击了父元素,这个时候,先触发子元素的事件处理器,然后再触发父元素的事件处理器,如果父元素的父元素还有处理器,就一直向上触发,一直到 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 

 

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议