DOM事件,捕获与冒泡处理,委托模式

事件流程

3阶段:

1 捕获阶段
事件应当从最顶层元素开始执行 一层层往下 直到最精确的元素
2 处于目标阶段
事件在最精确的元素身上执行
3 冒泡阶段
事件应当从最精确元素开始执行 一层层往上 直到最顶层元素
最顶层元素: IE8及以下中 最顶层元素是document
高级浏览器中 最顶层元素是window
之前介绍的 元素.on事件类型 = 函数 这种方式 是DOM0级事件绑定方式 它只能够绑定到冒泡阶段

			 window.onclick = function() {
		            console.log("window");
		        }
		        document.onclick = function() {
		            console.log("document");
		        }
		        document.documentElement.onclick = function() {
		            console.log("html");
		        }
		        document.body.onclick = function() {
		            console.log("body")
		        }
		        //运行结果:body
									html
									document
									window
DOM2级事件绑定方式

元素.addEventListener(type, handler, boolean);
type 事件类型字符串 不带on
handler 事件处理函数
boolean 布尔值 如果值为true 该绑定是绑定到捕获阶段 否则绑定到冒泡阶段

元素.removeEventListener(type, handler, boolean);
type 事件类型字符串 不带on
handler 事件处理函数
boolean 布尔值 如果值为true 该移除是移除捕获阶段 否则移除冒泡阶段

IE8 浏览器及以下的浏览器 不支持addEventListener
元素.attachEvent(type, handler)
type 事件类型字符串 带on
handler 事件处理函数
没有第三个参数 表示不能绑定到捕获阶段
元素.detachEvent(type, handler)
type 事件类型字符串 带on
handler 事件处理函数

注:想要移除的时候,一定要确保移除的函数就是绑定的函数
注:当处于目标阶段时,事件的执行不分捕获与冒泡,而是依照绑定顺序依次执行

					<script>
					        // 定义变量 简化书写
					        var w = window;
					        var d = document;
					        var h = document.documentElement;
					        var b = document.body;
					        // 给window添加点击事件
					        w.onclick = function() {
					            console.log("我是window冒泡")
					        }
					        // 给document添加点击事件
					        d.onclick = function() {
					            console.log("我是document冒泡")
					        }
					        // 给html添加点击事件
					        h.onclick = function() {
					            console.log("我是html冒泡")
					        }
					        // 给body添加点击事件
					        b.onclick = function() {
					            console.log("我是body冒泡")
					        }
					        // 通过dom2级方式绑定事件到捕获阶段
					        w.addEventListener("click", function() {
					            console.log("我是window捕获")
					        }, true)
					        d.addEventListener("click", function() {
					            console.log("我是document捕获")
					        }, true)
					        h.addEventListener("click", function() {
					            console.log("我是html捕获")
					        }, true)
					        b.addEventListener("click", function() {
					            console.log("我是body捕获")
					        }, true)
					    </script>

运行结果如图:
在这里插入图片描述

阻止冒泡

阻止冒泡指的是当子元素的事件触发之后 不要让父元素的事件触发
事件流程分捕获与冒泡,通常我们只会往冒泡阶段添加事件。
有些时候,我们希望子元素执行事件,父元素不执行事件。

  • 高级浏览器中
    • e.stopPropagation()
  • IE浏览器中
    • e.cancelBubble = true;

阻止冒泡案例(让放大和移动可以不受对方影响)

功能分析:
1 当按住裁剪区域(亮的部分)并拖动时 可以左右 上下移动
按住: mousedown
拖动: mousemove
在mousemove事件中改变定位值
要求计算定位值的变化 = 鼠标的变化量(鼠标移动之后的位置减去鼠标按下的位置)
2 当按住右下角的点并拖动时 可以改变裁剪区域的大小
按住: mousedown
拖动: mousemove
在mousemove事件中改变宽高
要求计算宽高的变化 = 鼠标的变化量(鼠标移动之后的位置减去鼠标按下的位置)

					<style>
								*{margin: 0;padding: 0;}
								#box{width: 430px; height: 430px; margin: 50px auto; border: 1px solid #000; background: url(./images/small.jpg) no-repeat 0 0;position: relative;}
								.mask{width: 100%;height: 100%; position: absolute;top: 0;left: 0; background: rgba(65,65,65,.4);}
								#area{width:200px;height: 200px; position: absolute;top: 0; left: 0; background: url(./images/small.jpg) no-repeat 0 0;}
								#dot{width: 10px;height: 10px; position: absolute; right: -5px; bottom: -5px; border-radius: 50%; background: orange;}
				 </style>
				 <body>
						    <div id="box" class="a">
							        <div class="mask"></div>
							        <div id="area" class="a">
							            <div id="dot" class="a"></div>
							        </div>
						    </div>
							<script>
				        //  获取元素
				        var area = document.getElementById("area");
				        var dot = document.getElementById("dot");
				        // 添加按住事件 也就是mousedown
				        area.onmousedown = function(e) {
				            // 获取鼠标按下时的位置
				            var mouseX = e.clientX;
				            var mouseY = e.clientY;
				            // 获取鼠标按下时的定位值
				            var left = area.offsetLeft;
				            var top = area.offsetTop;
				            // 添加mousemove事件
				            document.onmousemove = function(e) {
				                // 获取鼠标现在的位置
				                var nowX = e.clientX;
				                var nowY = e.clientY;
				                // 计算变化量
				                var resultX = nowX - mouseX + left;
				                var resultY = nowY - mouseY + top;
				                area.style.left = resultX + "px";
				                area.style.top = resultY + "px";
				                area.style.backgroundPositionX = - resultX + "px";
				                area.style.backgroundPositionY = - resultY + "px";
				            }
				        }
				       document.onmouseup = function() {
				            document.onmousemove = null;
				        }
				        // 添加小圆点的按住事件 也就是onmousedown事件
				        dot.onmousedown = function(e) {
				            e.stopPropagation();
				            // 记住按下时的宽度高度
				            var width = area.clientWidth;
				            var height = area.clientHeight;
				            // 记住按下时的鼠标位置
				            var mouseX = e.clientX;
				            var mouseY = e.clientY;
				            // 添加移动事件
				            document.onmousemove = function(e) {
				                // 记住移动之后的位置
				                var nowX = e.clientX;
				                var nowY = e.clientY;
				                // 计算变化
				                var resultX = width + nowX - mouseX;
				                var resultY = height + nowY - mouseY;
				                area.style.width = resultX + "px";
				                area.style.height = resultY + "px";
				            }
				        }

运行结果: 在这里插入图片描述

停止默认行为

在浏览器中,有许许多多的元素,有一些元素是具备默认行为的
比如:
a标签点击的时候会默认跳转页面
dom0级事件阻止a标签跳转,两种方法,1.return false (只适用用0级)
2 .e.preventDefault();

var a = document.getElementsByTagName("a")[0];
    a.onclick = function(e) {
        alert(123)
        // 如果不希望跳转 可以阻止默认行为 
        // 1 只适用于dom0级
        // return false;
        // 2 通过事件对象
        // e.preventDefault();
    }
   a.addEventListener("click", function(e) {
        // 只能用这种
         e.preventDefault();
        // dom2级中 return false无法阻止默认行为
        // return false;
    // })

submit按钮点击时会默认触发表单的submit事件

<form action='/a' method="get">
    用户名: <input type="text" name="username"  >
    密码: <input type="password" name="password"  >
    邮箱: <input type="text" name="email"  >
    提交: <button>如果我出现在form中并且没有指定type 则默认为submit</button>
</form>
<script>
    var inputs = document.getElementsByTagName("input");
    var button = document.getElementsByTagName("button")[0];
    button.onclick = function(e) {
        var flag = true;
        for (var i = 0; i < inputs.length; i++) {
            if (inputs[i].value === "") {
                flag = false;
                break;
            }
        }
        // flag代表是否有空值 为真表示没有空值 为假表示有空值
        if (!flag) {
            // 为假时会执行这里的代码 不要提交
            e.preventDefault();
        }
    }

委托模式

使用案例:

					<body>
					    <table>
					        <thead>
					            <tr>
					                <th>姓名</th>
					                <th>年龄</th>
					                <th>性别</th>
					                <th>操作</th>
					            </tr>
					        </thead>
					        <tbody>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					                <tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>
					        </tbody>
					    </table>  
					    <button id="btn">点我增加数据</button>
					    <script>
					        // 获取tbody
					        var tbody = document.querySelector("tbody");
					        // 获取btn
					        var btn = document.querySelector("#btn");
					
					        btn.onclick = function() {
					            tbody.innerHTML += "<tr><td>张三</td><td>22</td><td>男</td><td>&times;</td></tr>"
					        }
					        // 使用委托模式
					        // 给tbody添加点击事件 
					        tbody.onclick = function(e) {
					            // 判定 如果是最后一个元素 我们就将当前的行移除
					            if (e.target === e.target.parentNode.lastChild) {
					                e.target.parentNode.remove();
					            }
					        }
					        // 使用方式: 将事件绑定给不会被移除的父元素 通过判定方式让代码只再符合某种条件时执行
					 </script>
					</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值