前言
今日2020年4月7日,敲完代码有点疲劳,去看了下b站的前端代码。发现有个font-size
自适应的js,里面有addEventListener
方法,刚好前段时间看到关于addEventListener
的参数的考题,查了下资料,做此总结。
正文
addEventListener事件监听
事件监听有3个参数(官方api):
网上有人说遇到事件监听有5个参数的(参考资料里有5个参数),我查了下资料,第四个和第五个参数的资料基本是2012左右的,可能是后面优化了,不过多了解下总归没错。
addEventListener(
type:String,
listener:Function,
useCaputer:Boolean(default:false),
priority:int(default:0),
useWeakReference:boolean (default:false)
)
// 第一个参数type:是监听类型,包括click,pressdown,mouseover等各类你能想象到的操作事件
// 第二个参数listener:是你在监听后要执行的方法,方法内容自定义
// 第三个参数useCaputer:译为是否使用捕捉,默认是false,如果3个元素分别属于祖父元素,父元素,子元素,
// 都增加了监听方法,执行顺序会:都是false,则子元素先触发;都是true,祖父元素先触发;有true有false,
// 设置为true的先触发,2个true则在外层的优先。
// 这里牵扯到“事件流”的概念,这里借用下参考资料《TerryChou的事件监听介绍》的答案:监听器在监听时有三个阶段:捕获阶段、目标阶段和冒泡阶段。
// 顺序为:捕获阶段(根节点到子节点检查是否调用了监听函数)→目标阶段(目标本身)→冒泡阶段(目标本身到根节点)。
// 此处的参数确定监听器是运行于捕获阶段、目标阶段还是冒泡阶段。
// 下面有具体实现例子
// 第四个参数priority:译为优先。优先级,因为同一个元素可以增加多个同类型的监听方法,所以在设置同一元素同一类型多个
// 监听的执行顺序时会用到
// 第五个参数useWeakReference:译为是否使用弱引用。强引用or弱引用,假如是强引用不会被当做垃圾回收掉
例子
情形1:
<div id="outDiv" >
<div id="middleDiv">
<div id="inDiv">请在此点击鼠标。</div>
</div>
</div>
<div id="info"></div>
<script>
var outDiv = document.getElementById("outDiv");
var middleDiv = document.getElementById("middleDiv");
var inDiv = document.getElementById("inDiv");
var info = document.getElementById("info");
// 情形一:
outDiv.addEventListener("click", function () { info.innerHTML += "outDiv" + "<br>"; }, false);
middleDiv.addEventListener("click", function () { info.innerHTML += "middleDiv" + "<br>"; }, false);
inDiv.addEventListener("click", function () { info.innerHTML += "inDiv" + "<br>"; }, false);
// 执行上述js,因为设置的都是false,那么就是非捕捉,顺序为从内向外,结果为:inDiv middleDiv outDiv
// 如果都是true,那么就是捕捉,顺序为从外向内,结果为:outDiv middleDiv inDiv
// 如果仅设置middle的为true,因为true会提高优先级,那么结果为:middleDiv inDiv outDiv
// 如果设置多个true,如设置outDiv和inDiv为true,根据提升的优先级以及捕捉顺序,结果为:outDiv inDiv middleDiv
</script>
情形2:
<div id="outDiv" >
<div id="middleDiv">
<div id="inDiv" onclick="todo()">请在此点击鼠标。</div>
</div>
</div>
<div id="info"></div>
<script>
var outDiv = document.getElementById("outDiv");
var middleDiv = document.getElementById("middleDiv");
var inDiv = document.getElementById("inDiv");
var info = document.getElementById("info");
outDiv.addEventListener("click", function () { info.innerHTML += "outDiv" + "<br>"; }, false);
middleDiv.addEventListener("click", function () { info.innerHTML += "middleDiv" + "<br>"; }, false);
inDiv.addEventListener("click", function () { info.innerHTML += "inDiv" + "<br>"; }, false);
function todo() {
info.innerHTML += "inDiv新增标签onclick方法" + "<br>"
}
inDiv.onclick = function() {
info.innerHTML += "inDiv新增onclick事件" + "<br>"
}
document.onclick = function () {
info.innerHTML += "新增的document的onclick事件" + "<br>"
}
// 由于网上也有说执行顺序为:在监听为false时,标签的onclick事件->document.onclick->addEventListener,特在此验证
// 首先我在inDiv上增加todo()方法,测试发现无论inDiv的监听无论改为true或false,标签的onclick事件优先级均大于监听事件
// 之后增加inDiv.onclick事件,发现这个事件会替换掉标签上的onclick事件,且优先级仍旧大于监听事件
// 接着增加document.onclick事件,发现无论监听事件true或者false,该事件均最后执行,优先级最低
// 结论:同一元素下,无论该元素的监听是否false或者true,标签的onclick事件优先级均大于监听,至于document.onclick,
// 没太弄明白为什么要比对这个的优先级,很明显优先级最低,低于监听,当然,如果是我理解有误烦请指正。
</script>
参考资料
- TerryChou的事件监听介绍:个人感觉很简单易懂,是本文的主要参考资料。
网友评论