在处理事件的时候,所有和事件相关的东西都封装到event这个对象里面。所以这个对象非常的重要。这个对象有非常多的内容,我们讨论几个计较常见和以及比较难区别的target和currentTarget。
常见属性
页面就是一个div,然后我们监听他的oclick事件。
type属性:
这个属性返回事件类型,我们监听的是点击事件,所以返回的是click,注意前面是没有加on的,别的事件都是类似的,只是没有开头的on。
boxContent.onclick = function (event) {
//事件类型
console.log("type:"+event.type);//click
}
clientX和clientY:
这个相对于视口原点,返回点击位置的坐标,非常好理解。
//相对于视口原点(左上角)
console.log("clientX:"+event.clientX+" clientY:"+event.clientY);
pageX和pageY:
相对于页面,当发生向下滚动的时候,相对于滚动前的原点((左上角))。和clientX/Y只是有没有滚动的区别。
//相对于页面,当发生向下滚动的时候,相对于滚动前的原点((左上角))
console.log("pageX:"+event.pageX+" pageY:"+event.pageY);
screenX和screenY:
相对于屏幕,而不是浏览器。
//相对于屏幕,而不是浏览器
console.log("screenX:"+event.screenX+" screenX:"+event.screenY);
下面的属性需要修改一下页面测试。
仅仅是在div里面套了一个span。
还是只监听div的onclick方法。
还是只监听div的onclick方法。
还是只监听div的onclick方法。
eventPhase:
我们分别点击黄色的span区域和绿色的div区域
//监听div的onclick方法
console.log("eventPhase:"+event.eventPhase);
分别输出3和2。那么3和2代表什么意思呢?其实就是指的下图的三个阶段。大部分浏览器默认情况下都是通过冒泡来处理的,也就是点击span的时候,div要在冒泡阶段(3)才能接收到这个事件。而直接点击div的时候,div在目标阶段(2)就开始处理事件了。也可以设置默认的处理方式为捕获(1)。得出的结果就是1和2。如果不能理解,仔细阅读上一篇文章。
target和currentTarget区别:
这个是最重要的一个内容的,前面的内容实际上很少用到,这个却比较常用。
还是上面的情况,如果我只是点击div的部分,那么这两个变量是一样的。
console.log(event.target===event.currentTarget)
但如果我点击的是span,就不一样了。我们还是要看上面这张图target指的就是target phase的这个target。也就是点击事件实际上是发生在span身上的(因为span是dom的最里层)。而我们的onclick监听是注册在div身上的,也就是处理是发生在div身上的,也就是我们的currentTarget。
这个内容非常重要,后面的内容需要这个为基础,好好理解一下。
//事件发生的地方
console.log(event.target);
//事件正在处理的地方
console.log(event.currentTarget);
常见方法
阻止默认行为
这个非常的简单,有些时候,我们不希望控件的默认按钮生效,例如没有权限,或者不能满足触发的条件。这时候就可以通过preventDefault阻止默认行为。
var a = document.querySelector("a");
a.onclick=function (event){
event.preventDefault()
}
阻止事件传递
实现下面的效果,div里面有span,span里面有button。监听这三个元素的捕获和冒泡。然后我们点击按钮。
<div class="box">
<span>
<button>按钮</button>
</span>
</div>
<style rel="stylesheet">
div {
width: 500px;
height: 500px;
background-color: lightgreen;
}
span {
display: block;
width: 200px;
height: 200px;
background-color: gold;
}
</style>
var divEl = document.querySelector(".box");
var spanEl = document.querySelector("span");
var btnEl = document.querySelector("button");
divEl.addEventListener("click",function (){
console.log("div的事件捕获监听");
},true)
spanEl.addEventListener("click",function (){
console.log("span的事件捕获监听");
},true)
btnEl.addEventListener("click",function (){
console.log("button的事件捕获监听");
},true)
divEl.addEventListener("click",function (){
console.log("div的事件冒泡监听");
})
spanEl.addEventListener("click",function (){
console.log("span的事件冒泡监听");
})
btnEl.addEventListener("click",function (){
console.log("button的事件冒泡监听");
})
就可以得到下面的结果。
这个执行顺序就是整个事件传递的过程,我们希望在某个过程后事件就停止传递。就可以下下面的代码。例如我想执行div的捕获后,也就是第一个事件后就立刻停止传递。就可以写下面的代码。
divEl.addEventListener("click",function (event){
console.log("div的事件捕获监听");
event.stopPropagation()
},true)
事件监听this的指向
我们直接打印就知道了。直接说结论,不管是通过什么方式监听,不管监听的元素是作为子元素或者父元素,this都指向这个元素自身。
divEl.addEventListener("click",function (event){
console.log(this)
})
divEl.onclick=function (){
console.log(this)
}
下面的等式都是返回true。
divEl.addEventListener("click",function (event){
console.log(this)
console.log(event.currentTarget===this)
console.log(divEl===this)
})