细谈JavaScript事件模型
js事件模型有哪些?
- 原始(DOM0级)事件模型
- DOM2级事件模型
- IE事件模型
原始(DOM0级)事件模型
特点:
①行内事件
<input type="button" onclick="console.log('我被点击了')" value="点我试试">
点击结果如图:
②以“on事件名”的方式
<div id="btn">点我试试</div>
<script>
document.getElementById("btn").onclick= ()=>{
console.log('我被点击了')
}
</script>
点击后的效果:
特性:
①没有事件的传播
②一个DOM对象只能注册一个类型的事件,后注册的事件会覆盖之前的事件。且只执行最后一个事件。
例如:
document.getElementById("btn").οnclick= ()=>{
console.log('我被点击了')
}
document.getElementById("btn").οnclick= ()=>{
console.log('我才是被点击了')
}
点击一次的效果如图:
消除
当我们想要解除DOM0级事件时,我们可以将事件对应的函数赋值为null
,以此消除事件。例如:
document.getElementById("btn").οnclick= null
取消默认动作
当我们想取消某些标签自身的默认行为的时候,我们可以将函数的返回值写成“return false"
例如:
<a id="iama" href="2.html">我是a标签</a>
<script>
document.getElementById("iama").onclick = ()=>{
console.log("我没跳转")
return false
}
</script>
效果如图:
我们无论点击a标签多少次,页面都没有跳转到"2.html"页面。
DOM2级事件模型
监听方法,注册和移除事件处理程序:注册:addEventListener()
和 移除 removeEventListener()
。
注册:
[object].addEventListener(‘事件名称’,方法名(函数),事件模型(true/false))
移除 :
[object].removeEventListener(‘事件名称’,方法名(函数),事件模型(true/false))
特点
①.有一个完整的事件传播
- 事件捕获:事件由document对象一直向下捕捉到目标元素
- 事件执行:目标对象的事件处理程序执行
- 事件冒泡:事件从目标元素上升到document
所有事件类型都会经历第一阶段,有的事件不会经历第三阶段(submit)
②.一个DOM对象能注册多个类型的事件,后注册的事件不会覆盖之前的事件 ,事件依次执行。
<div id = 'outdiv' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
<div id="indiv" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div>
</div>
<script>
var click = document.getElementById('indiv');
click.addEventListener('click',function(){
console.log('click one');
},false);
click.addEventListener('click',function(){
console.log('click two');
},false);
</script>
结果:
停止传播
停止传播:event.stopPropagation()
当我们在不移除的前提
下想要继续传播的事件不执行
时,我们就可将事件对象event
调用stopPropagation()。
<div id='outdiv' style='margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
<div id="indiv" style='margin-left:20px; width: 50px;height:50px; background: green;'></div>
</div>
<script>
var click = document.getElementById('indiv');
var clickouter = document.getElementById('outdiv');
click.addEventListener('click',function(event){
console.log("indiv show");
event.stopPropagation();
},false);
clickouter.addEventListener('click',function(){
console.log("outdiv show");
},false);
</script>
效果如图:
点击indiv后
本应通过冒泡
同时执行的outdiv上
注册的事件不再执行
。
阻止默认动作
阻止默认动作:event.preventDefault();
<a id="iama" href="2.html">我是a标签</a>
<script>
document.getElementById("iama").addEventListener('click',function(event){
console.log("我没跳转");
event.preventDefault()
},false);
</script>
效果如图:
我们无论点击a标签多少次,页面都没有跳转到"2.html"页面。
IE事件模型
特点:Event对象不是事件处理程序的函数参数,而是window的全局变量
事件对象event:事件发生时产生的对象。封装了跟事件相关的信息。
–鼠标信息
–键盘信息
IE得到的事件对象
div1.onclick = function(){
var e = window.event;
}
DOM得到事件对象
div1.onclick = function(ev){
var e = ev;
}
事件传播过程只有冒泡阶段
注册:
[object].attachEvent(“onclick”,click1)
解除:
[object].detachEvent(“onclick”,click1)
停止传播:window.ecent.cancelBubble=true;
拓展:什么是冒泡和捕获?
冒泡和捕获
冒泡:(默认 ,第三个参数为false ,可以省略)
<div id="block1">
<div id="block2">
<div id="block3">点击</div>
</div>
</div>
document.getElementById("block1").addEventListener("click", function(){
console.log('点击了block1!');
});
document.getElementById("block2").addEventListener("click", function(){
console.log('点击了block2!');
});
document.getElementById("block3").addEventListener("click", function(){
console.log('点击了block3!');
});
执行顺序
:(由内向外)‘点击了block3!’—>‘点击了block2!’—>‘点击了block1!’。
捕获:( 第三个参数为true)
document.getElementById("block1").addEventListener("click", function(){
console.log('点击了block1!');
},true);
document.getElementById("block2").addEventListener("click", function(){
console.log('点击了block2!');
},true);
document.getElementById("block3").addEventListener("click", function(){
console.log('点击了block3!');
},true);
执行顺序:(由外向内)‘点击了block1!’—>‘点击了block2!’—>‘点击了block3!’。