添加事件的方法
- HTML-on屬性
和后面兩種方式不同,on屬性的值是將會執行的代碼,而不是一個函數。
只會在冒泡階段觸發
<body onload="doSomething()">
<div onclick="console.log('觸發事件')">
- element節點的事件屬性
監聽函數只會在冒泡階段觸發
兼容性好,但是同一個事件只能綁定一個監聽函數 - addEventListener方法
參數一:事件名稱,大小寫敏感
參數二:監聽函數
參數三:可省,默認為false,只在冒泡階段觸發
同一個事件能綁定多個監聽函數
div1.addEventListener('click',function(){
alert(2)
})
移除事件的方法
function fn(){
alert(2)
}
div1.addEventListener('click',fn)
div1.removeEventListener('click',fn)
//這種方法并不能移除事件,因為兩個函數的內存地址不同
div1.addEventListener('click',function(){
alert(2)
})
div1.removeEventListener('click',function(){
alert(3)
})
事件的傳播機制
當用戶點擊頁面時,瀏覽器總是假定用戶點擊的是點擊位置嵌套最深的節點
DOM2級規定事件有三個階段:
1.從window對象到目標節點,捕獲階段
2.在目標節點上觸發,目標階段
3.從目標節點傳導到window對象,冒泡階段
<div class='container'>
<div class="box">
<button type="" class="btn">按鈕</button>
</div>
</div>
<script>
var container=document.querySelector('.container')
var box=document.querySelector('.box')
var btn=document.querySelector('.btn')
container.addEventListener('click',function(){
console.log('clicked container...')
})
box.addEventListener('click',function(){
console.log('clicked box...')
})
btn.addEventListener('click',function(){
console.log('clicked btn...')
})
this指向
addEventListener方法指定的監聽函數,內部的this對象總是指向觸發事件的那個節點
以下寫法的this對象都指向Element節點。
// JavaScript代碼
element.onclick = print
element.addEventListener('click', print, false)
element.onclick = function () {console.log(this.id);}
// HTML代碼
<element onclick="console.log(this.id)">
以下寫法的this對象,都指向全局對象。
// JavaScript代碼
element.onclick = function (){ doSomething() };
element.setAttribute('onclick', 'doSomething()');
// HTML代碼
<element onclick="doSomething()">
event對象
事件發生后,會生成一個事件對象,作為參數,傳遞給監聽函數
event.currentTarget
綁定事件的節點
event.target
瀏覽器假定用戶點擊的深層節點
使用事件代理
<ul class="ct">
<li>這里是</li>
<li>饑人谷</li>
<li>前端6班</li>
</ul>
<script>
var ct = document.querySelector('.ct')
ct.addEventListener('click',function(e){
if(e.target.tagName.toLowerCase()==='li'){
console.log(e.target.innerText)
}
})
</script>
如何阻止事件冒泡? 如何阻止默認事件?
在事件的監聽函數中使用:
e.stopPropagation()
e.preventDefault()
<div class='container'>
<div class="box">
<button type="" class="btn">按鈕</button>
</div>
</div>
<a >點擊鏈接跳轉到百度</a>
<script>
var container=document.querySelector('.container')
var box=document.querySelector('.box')
var btn=document.querySelector('.btn')
var a=document.querySelector('a')
container.addEventListener('click',function(e){
console.log('clicked container...')
})
box.addEventListener('click',function(){
console.log('clicked box...')
})
btn.addEventListener('click',function(e){
e.stopPropagation() // 阻止事件冒泡
console.log('clicked btn...')
})
a.addEventListener('click',function(e){
e.preventDefault() // 阻止默認事件
alert(1)
})
</script>
DOM0 事件和DOM2級在事件監聽使用方式上有什么區別?
DOM0級
- HTML語言,允許在元素標簽屬性中,直接定義某些事件的監聽代碼。在HTML標簽的on屬性上,定義要執行的代碼
<p onclick='console.log(2)'></p>
- Element節點有事件屬性,可以指定監聽函數
ele.onclick=function(){}
DOM2級
通過Element節點Document節點,Window對象的addEventListener 和 removeEventListener方法
window.addEventListener('load', doSomething, false)
第一種“HTML標簽的on-屬性”,違反了HTML與JavaScript代碼相分離的原則;第二種“Element節點的事件屬性”的缺點是,同一個事件只能定義一個監聽函數,也就是說,如果定義兩次onclick屬性,后一次定義會覆蓋前一次。因此,這兩種方法都不推薦使用,除非是為了程序的兼容問題,因為所有瀏覽器都支持這兩種方法。
addEventListener是推薦的指定監聽函數的方法。它有如下優點:
1.可以針對同一個事件,添加多個監聽函數。
2.能夠指定在哪個階段(捕獲階段還是冒泡階段)觸發回監聽函數。
3.除了DOM節點,還可以部署在window、XMLHttpRequest等對象上面,等于統一了整個JavaScript的監聽函數接口。