前言
今日2020年4月7日剧辐,敲完代碼有點(diǎn)疲勞寒亥,去看了下b站的前端代碼。發(fā)現(xiàn)有個(gè)font-size
自適應(yīng)的js荧关,里面有addEventListener
方法溉奕,剛好前段時(shí)間看到關(guān)于addEventListener
的參數(shù)的考題,查了下資料忍啤,做此總結(jié)加勤。
正文
addEventListener事件監(jiān)聽
事件監(jiān)聽有3個(gè)參數(shù)(官方api):
網(wǎng)上有人說遇到事件監(jiān)聽有5個(gè)參數(shù)的(參考資料里有5個(gè)參數(shù)),我查了下資料檀轨,第四個(gè)和第五個(gè)參數(shù)的資料基本是2012左右的胸竞,可能是后面優(yōu)化了欺嗤,不過多了解下總歸沒錯(cuò)参萄。
addEventListener(
type:String,
listener:Function,
useCaputer:Boolean(default:false),
priority:int(default:0),
useWeakReference:boolean (default:false)
)
// 第一個(gè)參數(shù)type:是監(jiān)聽類型,包括click,pressdown,mouseover等各類你能想象到的操作事件
// 第二個(gè)參數(shù)listener:是你在監(jiān)聽后要執(zhí)行的方法煎饼,方法內(nèi)容自定義
// 第三個(gè)參數(shù)useCaputer:譯為是否使用捕捉讹挎,默認(rèn)是false,如果3個(gè)元素分別屬于祖父元素吆玖,父元素筒溃,子元素,
// 都增加了監(jiān)聽方法沾乘,執(zhí)行順序會(huì):都是false怜奖,則子元素先觸發(fā);都是true翅阵,祖父元素先觸發(fā)歪玲;有true有false,
// 設(shè)置為true的先觸發(fā)掷匠,2個(gè)true則在外層的優(yōu)先滥崩。
// 這里牽扯到“事件流”的概念,這里借用下參考資料《TerryChou的事件監(jiān)聽介紹》的答案:監(jiān)聽器在監(jiān)聽時(shí)有三個(gè)階段:捕獲階段讹语、目標(biāo)階段和冒泡階段钙皮。
// 順序?yàn)椋翰东@階段(根節(jié)點(diǎn)到子節(jié)點(diǎn)檢查是否調(diào)用了監(jiān)聽函數(shù))→目標(biāo)階段(目標(biāo)本身)→冒泡階段(目標(biāo)本身到根節(jié)點(diǎn))。
// 此處的參數(shù)確定監(jiān)聽器是運(yùn)行于捕獲階段顽决、目標(biāo)階段還是冒泡階段短条。
// 下面有具體實(shí)現(xiàn)例子
// 第四個(gè)參數(shù)priority:譯為優(yōu)先。優(yōu)先級才菠,因?yàn)橥粋€(gè)元素可以增加多個(gè)同類型的監(jiān)聽方法茸时,所以在設(shè)置同一元素同一類型多個(gè)
// 監(jiān)聽的執(zhí)行順序時(shí)會(huì)用到
// 第五個(gè)參數(shù)useWeakReference:譯為是否使用弱引用。強(qiáng)引用or弱引用鸠儿,假如是強(qiáng)引用不會(huì)被當(dāng)做垃圾回收掉
例子
情形1:
<div id="outDiv" >
<div id="middleDiv">
<div id="inDiv">請?jiān)诖它c(diǎn)擊鼠標(biāo)屹蚊。</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);
// 執(zhí)行上述js厕氨,因?yàn)樵O(shè)置的都是false,那么就是非捕捉汹粤,順序?yàn)閺膬?nèi)向外命斧,結(jié)果為:inDiv middleDiv outDiv
// 如果都是true,那么就是捕捉嘱兼,順序?yàn)閺耐庀騼?nèi)国葬,結(jié)果為:outDiv middleDiv inDiv
// 如果僅設(shè)置middle的為true,因?yàn)閠rue會(huì)提高優(yōu)先級芹壕,那么結(jié)果為:middleDiv inDiv outDiv
// 如果設(shè)置多個(gè)true汇四,如設(shè)置outDiv和inDiv為true,根據(jù)提升的優(yōu)先級以及捕捉順序踢涌,結(jié)果為:outDiv inDiv middleDiv
</script>
情形2:
<div id="outDiv" >
<div id="middleDiv">
<div id="inDiv" onclick="todo()">請?jiān)诖它c(diǎn)擊鼠標(biāo)通孽。</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新增標(biāo)簽onclick方法" + "<br>"
}
inDiv.onclick = function() {
info.innerHTML += "inDiv新增onclick事件" + "<br>"
}
document.onclick = function () {
info.innerHTML += "新增的document的onclick事件" + "<br>"
}
// 由于網(wǎng)上也有說執(zhí)行順序?yàn)椋涸诒O(jiān)聽為false時(shí),標(biāo)簽的onclick事件->document.onclick->addEventListener睁壁,特在此驗(yàn)證
// 首先我在inDiv上增加todo()方法背苦,測試發(fā)現(xiàn)無論inDiv的監(jiān)聽無論改為true或false,標(biāo)簽的onclick事件優(yōu)先級均大于監(jiān)聽事件
// 之后增加inDiv.onclick事件潘明,發(fā)現(xiàn)這個(gè)事件會(huì)替換掉標(biāo)簽上的onclick事件行剂,且優(yōu)先級仍舊大于監(jiān)聽事件
// 接著增加document.onclick事件,發(fā)現(xiàn)無論監(jiān)聽事件true或者false钳降,該事件均最后執(zhí)行厚宰,優(yōu)先級最低
// 結(jié)論:同一元素下,無論該元素的監(jiān)聽是否false或者true遂填,標(biāo)簽的onclick事件優(yōu)先級均大于監(jiān)聽铲觉,至于document.onclick,
// 沒太弄明白為什么要比對這個(gè)的優(yōu)先級城菊,很明顯優(yōu)先級最低备燃,低于監(jiān)聽,當(dāng)然凌唬,如果是我理解有誤煩請指正并齐。
</script>
參考資料
- TerryChou的事件監(jiān)聽介紹:個(gè)人感覺很簡單易懂,是本文的主要參考資料客税。