事件綁定
直接在dom元素上綁定一個(gè)事件,這是最簡單的方法孩饼,也是最不好的方法,比如在多個(gè)js文件中有可能會(huì)覆蓋掉之前的文件
var ul = document.getElementById('ul')
console.log(ul)
ul.onclick = function() {
console.log('click 事件綁定成功') // 并不會(huì)觸發(fā)
}
ul.onclick = function(){
console.log('click2事件綁定成功')
}
事件監(jiān)聽
事件監(jiān)聽實(shí)現(xiàn)的功能和直接綁定差不多才写,但是新增了一個(gè)特點(diǎn)葡兑。那就是無論監(jiān)聽次,都不會(huì)覆蓋掉前面的監(jiān)聽事件赞草。本質(zhì)原因是監(jiān)聽事件每次都會(huì)生產(chǎn)一個(gè)全新的匿名函數(shù)讹堤,和前面的函數(shù)完全不同,自然不會(huì)覆蓋厨疙。
事件冒泡和捕獲
事件捕獲:當(dāng)某個(gè)元素觸發(fā)某個(gè)事件(如onclick)洲守,頂層對(duì)象document就會(huì)發(fā)出一個(gè)事件流,隨著DOM樹的節(jié)點(diǎn)向目標(biāo)元素節(jié)點(diǎn)流去,直到到達(dá)事件真正發(fā)生的目標(biāo)元素梗醇。在這個(gè)過程中知允,事件相應(yīng)的監(jiān)聽函數(shù)是不會(huì)被觸發(fā)的。
事件目標(biāo):當(dāng)?shù)竭_(dá)目標(biāo)元素之后叙谨,執(zhí)行目標(biāo)元素該事件相應(yīng)的處理函數(shù)温鸽。如果沒有綁定監(jiān)聽函數(shù),那就不執(zhí)行手负。
事件冒泡:從目標(biāo)元素開始涤垫,往頂層元素傳播。途中如果有節(jié)點(diǎn)綁定了相應(yīng)的事件處理函數(shù)竟终,這些函數(shù)都會(huì)被一次觸發(fā)蝠猬。
阻止事件冒泡的的方法
- e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)
- 我們也能通過改變addEventListener的第三個(gè)參數(shù)改變事件的執(zhí)行順序。(false為冒泡階段執(zhí)行统捶,true為捕獲階段執(zhí)行榆芦,默認(rèn)為false)
事件委托
通俗的來講就是把一個(gè)元素的響應(yīng)事件函數(shù),委托到另一個(gè)元素瘾境。
舉個(gè)例子歧杏,就是有一堆li標(biāo)簽礁阁,需要給每一個(gè)li標(biāo)簽添加click事件筹陵,但是如果有幾萬個(gè)li標(biāo)簽中贝,每個(gè)標(biāo)簽都顯式地去添加事件函數(shù)笙以,會(huì)影響性能饱苟。這里有一個(gè)解決方案就是把li的事件函數(shù)埃碱,委托到它的上一層父級(jí)ul標(biāo)簽去(假如它的父級(jí)是ul)
<body>
<ul id='list'>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</body>
<script>
document.getElementById('list').addEventListener('click', function(e) {
var event = e || window.event
var target = e.target || event.srcElement
var nodeNameTemp = target.nodeName.toLocaleLowerCase()
if(target.nodeName.toLocaleLowerCase() === 'li') {
console.log('this content is :', target.innerHTML);
}
})
</script>
這里首先在父級(jí)ul上定義一個(gè)事件監(jiān)聽旅挤,變量event是回調(diào)函數(shù)獲取到的事件對(duì)象饵婆,target變量是#list元素下被點(diǎn)擊的li目標(biāo)元素礼华,通過這個(gè)target變量咐鹤,我們可以獲取一些例如nodeName和id這種屬性。然后就是通過屬性判斷是否是點(diǎn)擊的li的一些邏輯圣絮。
一些啟發(fā)祈惶,在純js編程中使用代理
dom事件的處理機(jī)制是依賴于瀏覽器的事件冒泡機(jī)制為dom添加事件按委托,同樣的我們?cè)趈s編程中也可以使用同類型的代理模式創(chuàng)建對(duì)象來操作目標(biāo)對(duì)象扮匠,來達(dá)到隱藏一些對(duì)象的目的捧请。
var delegate = function(client, clientMethod) {
return function() {
clientMethod.apply(client, arguments)
}
}
var classA = function(){
var color = 'red'
return {
getColor: function() {
console.log('color: ', color)
},
setColor: function(_color){
color = _color
}
}
}
var tempA = new classA()
tempA.getColor()
tempA.setColor('green')
tempA.getColor()
console.log('delegate start------')
var delegateTemp = delegate(tempA, tempA.setColor)
delegateTemp('blue')
console.log("delegete finish");
tempA.getColor();