添加事件的方法
- 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 href="http://www.baidu.com">点击链接跳转到百度</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的监听函数接口。