javascript 事件模型或者叫做事件机制都是一个东西,下面开始笔记:
分类: DOM0级事件模型, DOM2级事件模型
DOM0级事件模型
DOM0级事件模型是早期的事件模型,比如说一个onclick事件,贡献代码:
<p id = 'click'>click me</p>
<script>
document.getElementById('click').onclick = function(event){
var event=event||window.event;
var target=event.target||event.srcElement
alert(target);
}
document.getElementById('click')= null; //让垃圾回收机制回收
</script>
好理解吧,但是肯定有不好的地方,那就是无法绑定多个相同的事件。
因为注册多个同类型的函数的话,就会发生覆盖,之前注册的函数就会无效
DOM1级事件模型
IE搞得冒泡和网景搞得捕获。两人谁也不服谁!就是干!
DOM2级事件模型 (w3c):事件捕获(123)和事件冒泡(4567)
假如说有两个嵌套的id为outer另外一个是idinner 假设我们点击了ID为inner的div,那么此时的事件流程就是,首先默认执行捕获阶段:document-html-body-div(outer)。然后执行冒泡阶段:div(inner)-div(outer)-body-html-document。
DOM2级的注册事件和解除事件
在DOM2级中使用addEventListener和removeEventListener来注册和解除事件(IE8及之前版本不支持attachEvent和removeEvent)。这种函数较之之前的方法好处是一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。
addEventListener('事件名称','事件回调','是否在捕获阶段执行')
attachEvent('事件名称','事件回调','是否在捕获阶段执行')
<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
<div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background:
green;'>
</div>
</div>
<script>
var click = document.getElementById('inner');
click.addEventListener('click',function(){
alert('click one');
},false);
click.addEventListener('click',function(){
alert('click two');
},false);
</script>
注意执行顺序会受到不同true or false方式的影响。
也会受到添加事件的顺序影响
<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
<div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background:
green;'>
</div>
</div>
<script>
var click = document.getElementById('inner');
var clickouter = document.getElementById('outer');
click.addEventListener('click',function(){
alert('inner show');
},true);
clickouter.addEventListener('click',function(){
alert('outer show');
},true);
</script>
这段代码,我们使用了捕获事件,由于inner是嵌套在outer中的
所以我们知道当使用捕获的时候outer是应该首先捕获到这个事件的
其次inner才能捕获到这个事件。那么结果就是outer首先执行,其次是inner执行。
如果这么改:就限先执行inner 在执行outer
clickouter.addEventListener('click',function(){
alert('outer show');
},false);
那么 如果我们给outer和inner都注册了click事件但是我不希望outer执行怎么办呢?
这个时候我们就需要用到stopPropagation函数了,这个函数是用来阻止冒泡,言下之意是让事件不再继续冒泡下去,这样接下来
注册同样类型事件的dom对象就不会执行了。
<script>
var click = document.getElementById('inner');
var clickouter = document.getElementById('outer');
click.addEventListener('click',function(event){
alert('inner show');
var event=event||window.event;
event.stopPropagation();
},false);
clickouter.addEventListener('click',function(){
alert('outer show');
},false);
</script>
这个时候就不会连续提示alert了
但是 我要是 把outer 变成true呢?
还是会执行的,并且先执行,因为是捕获在先
并且event.stopPropagation(); 不起作用
所以:由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡。
再说一点:
W3C模型使用addEventListener兼容IE8以上的所有浏览器(ie 8 9 10 谷歌等),阻止冒泡用的是event.stopPropagation()阻止默认动作是event.preventDefault()!!!
IE模型用attachEvent,兼容IE8以下浏览器(ie 6 7),阻止冒泡 event.cancelBubble=true,阻止默认 event.returnValue=false
所以你在使用时要做浏览器是否支持W3C和IE模型的判断。