• javascript事件机制了解与深入


    一、事件的捕获与冒泡

        “DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。下面这个图能够很形象的解释(理解捕获和冒泡必不可少的图)

    59e2d17f-ae58-4591-bd37-93ebe7f0b5ee

    按照图我们编写了代码去验证下,

    <div id="parent">
    
        <div id="child">
    
            child
    
        </div>
    
    </div>
    
    <script type="text/javascript">
    
        var p = document.getElementById('parent'),
    
                c = document.getElementById('child');
    
        p.addEventListener('click', function (e) {
    
            console.log('父节点捕获')
    
        }, true);
    
        c.addEventListener('click', function (e) {
    
            console.log('子节点捕获')
    
        }, true);
    
        c.addEventListener('click', function (e) {
    
            console.log('子节点冒泡');
    
        }, false);
    
       p.addEventListener('click', function (e) {
    
           console.log('父节点冒泡')
    
       }, false);
    
    </script>
    View Code

    结果一目了然

    992dead0-0481-4660-8a6d-dde631cf236d

    但是这里有个问题,也是原来阿里的面试题目,

    若是一个dom上绑定了两次事件,一个捕获,一个冒泡的,事件执行顺序是什么呢,

    这个在参考小胡子哥的写js事件机制的博客中了解到,顺序是和绑定顺序有关系的,那我们来试一下,

    <div id="parent" style="height: 300px; background-color: #ccc;">
    
        <div id="child">
    
            child
    
        </div>
    
        <p>other child</p>
    
    </div>
    
    <script type="text/javascript">
    
        var p = document.getElementById('parent'),
    
                c = document.getElementById('child');
    
        p.addEventListener('click', function (e) {
    
            console.log('父节点冒泡')
    
        }, false);
    
        c.addEventListener('click', function (e) {
    
            console.log('子节点冒泡');
    
        }, false);
    
        c.addEventListener('click', function (e) {
    
            console.log('子节点捕获')
    
        }, true);
    
        p.addEventListener('click', function (e) {
    
            console.log('父节点捕获')
    
        }, true);
    
    </script>
    View Code

    60467b7e-cffe-4953-9d80-3e7c1a80a878

    当点击1时

    6135b410-6f49-4ef1-a71f-f7a78a96043a

    当点击2时

    4aa11a0c-8119-4245-bb54-6d9840f16e18

    当点击3时

    491becc5-6e53-449b-ae3b-b8b5a376d43c

    我们发现1和3的情况下是先冒泡后捕获的,代码中我将冒泡的的绑定事件写到捕获前面了,造成了这样的效果,

    事件目的地节点既绑定了冒泡事件也绑定了捕获事件,此时的执行顺序按照绑定的先后顺序执行

    那第二种为什么顺序是先捕获后冒泡的呢,是因为事件目的地点 other child没有绑定事件。

    有捕获和冒泡就有相应的阻止,stopPropagation这个应该是阻止事件的下一步传播,stopImmediatePropagation这个方法能把绑定在这个元素上的事件都能阻止掉,可以了解下。

    另附,易混淆的,

    event.prevetDefault() => 默认事件
    event.stopPropogation() => 事件捕获、事件冒泡,事件代理
    return false => jquery内部就是调用了上面两个实现的。

    二,事件委托机制

    对“事件处理程序过多”问题的解决方案就是事件委托,事件委托利用了事件冒泡,只指定一个事件处理程序,就能管理这一类型的所有事件。

    比如对ul下的li绑定事件,一般是遍历li,给每个li绑定事件,这个有两个问题,1,如果是新加的li,我们需要重新绑定。2,如果li有很多,那占用内存会很多。

    那我们这个时候就可以用事件委托了,委托在词典中解释,将自己的事务嘱托他人代为处理。那就是事件我不放到要处理的dom上面,也就是利用冒泡的原理,将事件绑定到父级上面。再按照每个触发事件的event对象找到target,说到这,又要说兼容问题了,w3c的标准下的,event.target即可,IE的确是event.srcElement。到这我想大家应该会想到一个神器,jQuery了,对的,他里面的绑定事件都是兼容的,都是封装好的,那他又是怎么处理的呢,好吧,要去解读源码了。

    参考博客:

    [解惑]JavaScript事件机制

    【探讨】javascript事件机制底层实现原理

  • 相关阅读:
    Android使用sqlliteOpenhelper更改数据库的存储路径放到SD卡上
    递归实现全排列(一)
    poj_1284_原根
    绝对让你理解Android中的Context
    Java Web---登录验证和字符编码过滤器
    ceph理论及部署配置实践
    ceph for openstack快速部署实施
    php set env
    基于本地iso 搭建的本地yum源 安装部署openldap
    ceph rpm foor rhel6
  • 原文地址:https://www.cnblogs.com/jesse-band/p/4458619.html
Copyright © 2020-2023  润新知