发表于: 2019-10-08 23:38:18
1 1460
今天完成的事
今天仔细学习了冒泡事件
冒泡事件:
定义:当多个Dom元素互相嵌套的时候,一个元素触发了某个事件(例如Click事件),那么嵌套此事件的所有元素都会被触发一次Click事件,注意:只会触发他的直系亲属元素,而与其自己,父级,爷级等等同级的亲戚集是不会触发的
捕获事件:
*定义:** 同冒泡事件含义相似,只是将冒泡事件的触发顺序倒过来即可
DOM事件流
元素的触发流程分为三个阶段
捕获阶段:先从祖先级一直找到触发的源元素(所有元素都触发了相同事件)
目标阶段:找到原元素,然后触发源元素的事件
冒泡阶段:然后重新流回祖先元素,又触发了一遍相同事件
思考: 按照上面的事件流,岂不是一个元素会触发两次事件?那这不是很奇怪吗:其实在我们一般开发过程中都是用Jquery 的 on 方法来绑定的(推荐使用),绑定后,只会触发冒泡事件。那么什么时候会涉及到这个捕获阶段呢,在原生的javascript中,就会有此方法的使用,且看下面详解
详解 addEventListener/removeEventListener
作用: 原生的事件绑定方法
// type:事件类型,不含"on",比如"click"、"mouseover"、"keydown";
// 而attachEvent的事件名称,含含"on",比如"onclick"、"onmouseover"、"onkeydown";
// listener:事件处理函数
// useCapture是事件冒泡,还是事件捕获(true),默认false,代表事件冒泡类型
addEventListener(type, listener, useCapture);特点:
一个元素可以同时绑定两种类型(捕获/冒泡)
一个同种类型的元素重复绑定同一个事件函数,只绑定一次
一个元素可以重复绑定多个不同的函数,且是叠加而非覆盖
触发流程:
首先源目标触发了事件
开始捕获阶段,将其直系亲属(类型为捕获)的事件触发
到达源元素,触发事件方法,如果重复绑定多个,则按绑定顺序触发(源元素的类型其实没有影响)
然后开始冒泡排序,将其直系亲属(类型为冒泡)的事件触发
<script>
window.onload = function(){
var outA = document.getElementById("outA");
var outB = document.getElementById("outB");
var outC = document.getElementById("outC");
// 目标(自身触发事件,是冒泡还是捕获无所谓)
outC.addEventListener('click',function(){alert("target2");},true);
outC.addEventListener('click',function(){alert("target1");},true);
// 事件冒泡
outA.addEventListener('click',function(){alert("bubble1");},false);
outB.addEventListener('click',function(){alert("bubble2");},false);
// 事件捕获
outA.addEventListener('click',function(){alert("capture1");},true);
outB.addEventListener('click',function(){alert("capture2");},true);
};
</script>
<body>
<div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
<div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
<div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div>
</div>
</div>
</body>
点击outC的时候,打印顺序是:capture1-->capture2-->target2-->target1-->bubble2-->bubble1结论:捕获阶段的处理函数最先执行,其次是目标阶段的处理函数,最后是冒泡阶段的处理函数。目标阶段的处理函数,先注册的先执行,后注册的后执行
如何解决冒泡/捕获事件的影响
目的: 我们很清楚,解决冒泡和捕获事件的影响,只需要在源元素触发完事件之后停止事件的传播即可
方式:
event.stopPropagation(); 只阻止了冒泡事件, 默认行为没有阻止(超链接a嵌套按钮,依然会跳转)
event.preventDefault(); 只阻止了默认事件,冒泡事件没有阻止(超链接a嵌套按钮,不跳转,但会触发点击事件)
return false; 冒泡事件和默认事件都阻止
<script>
window.onload = function(){
var outA = document.getElementById("outA");
var outB = document.getElementById("outB");
var outC = document.getElementById("outC");
// 目标
outC.addEventListener('click',function(event){
alert("target");
event.stopPropagation();
},false);
// 事件冒泡
outA.addEventListener('click',function(){alert("bubble");},false);
// 事件捕获
outA.addEventListener('click',function(){alert("capture");},true);
};
</script>
<body>
<div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
<div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
<div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div>
</div>
</div>
</body>
capture-->target,不会打印出bubble。因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件的继续传播,所以不会继续传播到冒泡阶段,当然如果此方法放到了捕获中,那么就只会打印出capture了注意点:
今天用 on 绑定的时候,div 嵌套按钮,按钮里的事件触发带有ajax的请求,结果点击确实进入了按钮事件方法中,但是还没有进入回调函数,就跳转到div的点击事件方法中了,然后再跳回回调方法中,采用了以下方法解决
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>webApi测试</title>
<script src="~/js/jquery.min.js"></script>
</head>
<body>
<div id="first">
</div>
<div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
<div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
<div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div>
</div>
</div>
</div>
</body>
</html>
<script>
$(function () {
$("#outC").on ("click",function () { alert("C")});
$("#outB").on ("click",function () { alert("B") });
$("#outA").on("click", function () { alert("A") });
$("#outD").on("click", function () { alert("D") });
$("#first").on("click", function () { debugger; alert("最外层div") });
$("#routeTest").on("click", ajaxFunction);
function ajaxFunction() {
debugger;
//event.cancelBubble = true;//取消事件的冒泡,效果同下
//return false//此方法会导致此方法直接结束,因此不能直接使用
event.stopPropagation();
$.ajax({
url: "/Course/GetCourseByRoute?temp"+Date.parse(new Date()),
type: 'get',
success: function (res) {
debugger;
alert(res);
}
});
}
});
</script>
把任务六静态页面快写完了,还差一个交互效果,就是点击摁扭使隐藏的列表显示出来并有滑动效果,这里我思考了一下午,总是会出bug。因为过度的css属性transition,只有改变宽度高度的数值时才有动画效果,display:none过渡到display:block时是没有动画效果的,因此想要有滑动的效果必须设置height的高度变化,但是因为列表里面还有隐藏列表,如果把外面列表高度限定死了了的话隐藏列表就没法出来,所以也不能把height写死,后来我想把高度设置成auto,但是这样就会失去滑动效果,想了很多办法,用min-height什么的都不行,总是会出现bug,最后在引用jQ之后才有效解决滑动动画的问题,但是又会出现一个新的bug,jQ是用改变style属性的方法来控制列表的,当一次点击之后style就会变成none;这样的话就会导致一个问题,变成这个样子,我想了一下最后用window的监听屏幕宽度的方法来解决,当屏幕宽度大于768时就设置取消掉style属性,这才彻底解决问题。
明天计划的事
写任务6与后台的交互展示
遇到的困难
不知道怎么用angular写手风琴,我都是用原生js写的。
收获
知道了怎么在angular里面引用jQ,知道了很多window事件。
评论