JS事件詳解(二) —— 事件處理程式(事件的繫結)
事件繫結方法
方法一:直接在HTML標籤中繫結
在html標籤中新增“on”+事件名稱的屬性來繫結事件
事件處理程式可直接寫在屬性值當中
<div class="demo" onclick="console.log(this)"></div> // this指向的是當前DOM物件
這種事件處理程式的作用域很特別,可以像區域性變數一樣直接訪問document及元素本身的成員,示例:
<div class="demo" onclick="console.log(className)"></div> // demo
// 等同於
<div class="demo" onclick="console.log(this.className)"></div>
當事件內容較為複雜的時候,可將事件內容寫成函式,在on的事件屬性中執行函式
<div onclick="demo()"></div>
<script>
function demo(){
console.log(this) // this指向window物件,只能通過傳參來獲取當前DOM元素
}
</script>
通過HTML繫結事件的缺點是HTML與JavaScript程式碼耦合嚴重
方法二:在js中在DOM元素上繫結
DOM元素新增‘on’+事件名稱的屬性,this指向的是當前的DOM物件
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.onclick=function(){
console.log(this) // this指向的是當前的DOM物件
}
</script>
與方法一類似,事件內容較為複雜或有多個元素需要繫結同一事件,可將事件另寫成個函式,元素只需呼叫該函式即可
<div class="demo1"></div>
<div class="demo2"></div>
<script>
var demo1=document.querySelector(".demo1"),
demo2=document.querySelector(".demo2")
function demoFunc(){
console.log(123)
}
demo1.onclick=demo2.onclick=demoFunc // 123 123
</script>
這種方法的缺點是DOM物件只能繫結一個事件處理程式,後面繫結的程式會覆蓋前面繫結的程式
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.onclick=function(){
console.log(123) // 不會執行
}
demo.onclick=function(){
console.log('abc') // abc
}
</script>
列印結果:abc
解除事件繫結
demo.onclick=null
方法三:使用addEventListener和attachEvent函式繫結
addEventListener函式是W3C標準規定的,IE8及IE8以下不支援
addEventListener(event,function,boolean)
event:事件名稱
function:事件處理程式的函式
boolean:false-冒泡階段呼叫程式 true-捕獲階段呼叫程式
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.addEventListener('click',function(){
console.log(this) // this指向當前DOM物件
},false)
</script>
這種方法可以給DOM物件繫結多個事件處理程式,按順序執行
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.addEventListener('click',function(){
console.log(123)
},false)
demo.addEventListener('click',function(){
console.log(456)
},false)
</script>
列印結果:123 456
繫結同一事件處理函式並且第三個引數一致,只會執行一次
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
function demoFunc(){
console.log(123)
}
demo.addEventListener('click',demoFunc,false)
demo.addEventListener('click',demoFunc,false) // 只能列印一次‘123’
</script>
列印結果:123
繫結同一事件處理函式但第三個引數不一致,會執行兩次
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
function demoFunc(){
console.log(123)
}
demo.addEventListener('click',demoFunc,false)
demo.addEventListener('click',demoFunc,true) // 列印兩次‘123’
</script>
列印結果:123 123
繫結相同的匿名函式,會執行兩次,兩個程式碼完全一樣的匿名函式是不相同的
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.addEventListener('click',function(){
console.log(123)
},false)
demo.addEventListener('click',function(){
console.log(123) // 列印兩次‘123‘
},false)
</script>
列印結果:123 123
解除事件繫結
demo.removeEventListener('click',demoFunc,false) // 不能解除匿名函式,且第三個引數必須一致
attachEvent函式是IE特有的,IE8以下瀏覽器可以使用,可新增多個事件處理函式,只支援冒泡階段
attachEvent(‘on’+event,function)
event:事件名稱
fucntion:事件處理程式
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.attachEvent('onclick',function(){
console.log(this) // this指向window物件
})
</script>
該方法同樣可以給DOM物件繫結多個事件處理程式,但是與addEventListener不同的是,attachEvent不是順序執行的,而是按相反順序執行的
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
demo.attachEvent('onclick',function(){
console.log(123) // 後執行
})
demo.attachEvent('onclick',function(){
console.log(456) // 先執行
},false)
</script>
列印結果:456 123
與addEventListener一樣,同一事件處理函式只能繫結一次,相同的匿名函式可以重複繫結
<div class="demo"></div>
<script>
var demo=document.querySelector(".demo")
function demofunc(){
console.log(123)
}
demo.attachEvent('onclick',demofunc)
demo.attachEvent('onclick',demofunc) // 呼叫兩次,只會列印一次‘123’
</script>
列印結果:123
var demo=document.querySelector(".demo")
demo.attachEvent('onclick',function(){
console.log(123)
})
demo.attachEvent('onclick',function(){
console.log(123) // 會列印兩個‘123’
})
列印結果:123 123
解除事件繫結
demo.detachEvent('onclick',demofunc) // 不能解除匿名函式
把事件繫結封裝成一個函式,相容各個瀏覽器
// 事件繫結
function addEvent(element, type, handler) {
if(element.addEventListener){ //如果支援addEventListener
element.addEventListener(type, handler, false);
}else if(element.attachEvent){ //如果支援attachEvent
element.attachEvent("on"+type, function(){
handler.call(element); // 將this指向當前DOM物件
});
}else{ //否則使用相容的onclick繫結
element["on"+type] = handler;
}
}
// 事件解綁
function removeEvent(element, type, handler) {
if(element.addEventListener){
element.removeEventListener(type, handler, false);
}else if(element.attachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
}
阻止預設事件
1.阻止通過on方法繫結事件的預設事件
demo.onclick=function(){
console.log(123)
return false
}
2.阻止通過addEventListener方法新增事件的預設事件
demo.addEventListener("click",function(e){
var event=e||window.event
console.log(123)
event.preventDefault()
},false)
3.阻止通過attachEvent方法新增事件的預設事件
demo.attachEvent("onclick",function(e){
var event=e||window.event
console.log(123)
event.returnValue=false
})