系统复习DOM事件模型

一.  DOM事件级别

dom事件级别包括dom0,dom2,dom3(dom1版本对dom事件没有任何修改)。这三种级别绑定事件的方法如下:

dom0绑定事件方法:

<p id = 'click'>click me</p>
<script>
    document.getElementById('click').onclick = function(event){
        alert(event.target);
    }
</script>

解绑事件方法:

document.getElementById('click'_).onclick = null;

dom3和dom2绑定事件的方法一样,就是多了很多事件类型,比如keyup,input等事件类型,目前主流浏览器都已经支持这些事件类型,这些事件类型不仅可以用dom0方式绑定,也可以用dom2方式绑定。

dom2,dom3绑定事件方法及解绑事件方法:

var click = document.getElementById('inner');
click.addEventListener('click',function(){
        alert('inner show');
    },false);
let testFun = function () {
        console.log("test111")
    }
let dom = document.getElementById('test1')

 /* addEventListener ie9以下不支持*/

dom.addEventListener('click',testFun,false)


dom.removeEventListener('click',testFun,false)



注意:这里有几个坑

1.用dom0方式绑定的事件方法,用dom2方式解绑方法是不行,总之就是何种级别绑定,就何种级别解绑。

2.addEventListener不支持ie9以下,需要考虑兼容写法,ie8以下是attachEven。

3.removeEventListener需要考虑两个方法用到的是同一个函数,否则remove无效。具体可自行搜索相关资料

4.dom0事件绑定方法,一次只能执行一个函数,多写几个,后面的会覆盖前面的,而dom2方式绑定的方法,可以依此执行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM 事件</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
</head>
<body>
<div id="test1">111111</div>
<script type="text/javascript">
    var dom = document.getElementById('test1');
    dom.onclick = function () {/*方法失效,被覆盖*/
        console.log("dom0-1")
    }
    dom.onclick = function () {/*只执行这个*/
        console.log("dom0-2")
    }

    /* dom2绑定事件兼容ie地低版本写法 */
    var Event = {};
    Event.addEvents = function(target,eventType,handle,arguments){
        if(document.addEventListener){
            target.addEventListener(eventType,handle,arguments?arguments:false);
        }else{
            target.attachEvent('on'+eventType,function(){
                handle.call(target,arguments);
            });
        }
    }
    Event.removeEvents = function(target,eventType,handle){
        if(document.removeEventListener){
            target.removeEventListener(eventType,handle,false);
        }else{
            target.detachEvent('on'+eventType,function(){
                handle.call(target,arguments);
            });
        }
    }

    var testFun = function () {
        console.log("dom2")
    }
    var testFun2 = function () {
        console.log("dom2-2")
    }

    Event.addEvents(dom,"click",testFun)/*可以执行*/
    Event.addEvents(dom,"click",testFun2)/*可以执行*/
    dom.onclick = null //解绑dom0方法,dom2方法依然执行
    Event.removeEvents(dom,"click",testFun)//解绑dom2方法
    
    /* 实践发现document改成window,在ie9以下无效*/
    document.onkeyup = function () {//能执行
        console.log("onkeyup1")
    }
    Event.addEvents(document,"keyup",function () {//能执行
        console.log("onkeyup2")
    })

</script>
</body>
</html>

二.  DOM事件模型

首先,IE8及以下是不支持这种事件模型的。事件捕获和事件冒泡的机制如下图:

DOM事件模型:浏览器在用户触发某个事件以后,先从window对象开始,然后从document,html,body,等等,依此层层捕获触发事件的目标元素,捕获到目标元素后,事件再依此从目标元素往上冒泡,依次是父元素,一层一层,到到body,html,ducument,window.

关键点:事件绑定,第三个参数默认false,即事件冒泡阶段处理事件函数,改为true,即在捕获阶段执行事件函数。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM 事件</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
</head>
<body>
<div id="parent">
    <div id="test1">点击我</div>
</div>

<script type="text/javascript">
    var dom = document.getElementById('test1');
    var parent = document.getElementById('parent');

    /* dom2绑定事件兼容ie地低版本写法 */
    var Event = {};
    Event.addEvents = function(target,eventType,handle,arguments){
        if(document.addEventListener){
            target.addEventListener(eventType,handle,arguments?arguments:false);
        }else{
            target.attachEvent('on'+eventType,function(){
                handle.call(target,arguments);
            });
        }
    }

    /*事件函数在捕获阶段执行*/
    Event.addEvents(document,'click',function () {
        console.log('document')
    },true)
    Event.addEvents(document.documentElement,'click',function () {
        console.log('html')
    },true)
    Event.addEvents(document.body,'click',function () {
        console.log('body')
    },true)
    Event.addEvents(parent,'click',function () {
        console.log('parent')
    },true)
    Event.addEvents(dom,'click',function () {
        console.log('dom')
    },true)

    /*事件函数在冒泡阶段执行*/
    Event.addEvents(document,'click',function () {
        console.log('document-2')
    })
    Event.addEvents(document.documentElement,'click',function () {
        console.log('html-2')
    })
    Event.addEvents(document.body,'click',function () {
        console.log('body-2')
    })
    Event.addEvents(parent,'click',function () {
        console.log('parent-2')
    })
    Event.addEvents(dom,'click',function () {
        console.log('dom-2')
    })

</script>
</body>
</html>

三.  DOM事件类

事件类封装了关于事件处理的很多api,常用的有:

1.preventDefault

应用例子:阻止a标签的默认跳转行为

如vue里面:

2.stopPropagation 阻止事件冒泡,太常用了,不举例了

3.stopImmediatePropagation:一个dom如果绑定多个事件函数,但是只想执行某些函数,其他函数不执行,可用该方法

<body>
<div id="parent">
    <div id="test1">111111</div>
</div>

<script type="text/javascript">
    var dom = document.getElementById('test1');

    /* dom2绑定事件兼容ie地低版本写法 */
    var Event = {};
    Event.addEvents = function(target,eventType,handle,arguments){
        if(document.addEventListener){
            target.addEventListener(eventType,handle,arguments?arguments:false);
        }else{
            target.attachEvent('on'+eventType,function(){
                handle.call(target,arguments);
            });
        }
    }

    Event.addEvents(dom,'click',function (event) {
        console.log("dom")
        event.stopImmediatePropagation()//增加这句后,其他事件函数就不执行了
    })
    Event.addEvents(dom,'click',function () {
        console.log("dom-2")
    })

    
</script>
</body>

4.event.target 和event.currentTarget :获取实际触发事件的dom元素,和绑定事件的dom元素,此方法即事件代理。

猜你喜欢

转载自blog.csdn.net/SunShinessx/article/details/87531096