zoukankan      html  css  js  c++  java
  • HTML 学习笔记 JavaScript(事件)

    事件流:

    事件流: 描述的是从页面中接收事件的顺序 也可以理解为事件在页面中传播的顺序;

    事件: 就是用户或浏览器自身执行的某种动作 例如 click(点击) load(加载) mouseover(鼠标悬停)

    事件处理程序: 响应某个事件的函数就叫事件处理程序(或事件侦听器)


    下面所示例子注册事件的方式均使用DOM2级事件定义的事件处理程序进行注册。DOM2级事件定义可两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),所有的DOM节点都包含这两个方法,并且它们都接收三个参数:处理事件的方式 作为事件处理程序的函数 和一个bool值。当这个Bool值为true时,表示在捕获阶段调用事件处理程序,如果为false 表示在冒泡阶段调用事件处理程序。

    事件的作用范围讨论

    示例1

    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                #wrap {
                    width: 200px;
                    height: 200px;
                    background: orange;
                }
                #outer {
                    position: relative;
                    top: 50px;
                    left: 50px;
                    width: 100px;
                    height: 100px;
                    background: #eeddff;
                }
                #liner {
                    position: relative;
                    top: 25px;
                    left: 25px;
                    width: 50px;
                    height: 50px;
                    background: #44ddff;
                }
            </style>
        </head>
        <body>
            <div id="wrap">
                <div id="outer">
                    <div id="liner">
                        
                    </div>
                </div>
            </div>
            
            <script>
                var wrap = document.getElementById("wrap");
                wrap.addEventListener("click",function(){
                    alert("1314");
                },false);
            </script>
            
        </body>
    </html>

    output

    问题1:容器元素wrap注册了事件,那么此事件的作用范围是什么?

    思考1:根据上面的例子 当点击橘黄色块中(包括被子元素覆盖的部分)任何一部分时,都会弹出1314,点击橘黄色块外面的部分没有任何反应,那么,我们可以得到这样的结论,元素注册事件的作用范围为元素自身在页面中所占空间的大小,但是真的是这样吗?下面我们来做个实验:

    我们可以更改上面代码中的CSS代码 改过后为这样:

    <style type="text/css">
        #wrap {
            width: 200px;
            height: 200px;
            background: orange;
        }
        #outer {
            position: relative;
            top: 50px;
            left: 50px;
            width: 100px;
            height: 100px;
            background: #eeddff;
        }
        /*liner中的top被修改*/
        #liner {
            position: relative;
            top: 152px;
            left: 25px;
            width: 50px;
            height: 50px;
            background: #44ddff;
        }
    </style>

    此时HTML页面是这样的:

    结论1:当橘黄色块外的浅蓝色部分被点击的时候,同样弹出了1314,而浅蓝色部分是嵌套在wrap元素之内的元素,故可以得出结论:当元素注册了事件,此事件的作用范围:1元素自己所占页面空间的加嵌套元素所占空间的范围(若嵌套元素覆盖在容器元素上,则此事件的作用范围为容器元素自身所占空间的大小)

    事件的执行顺序的讨论

    问题2 根据上面的示例 那么这里大家可以在思考一个问题,若容器元素wrap以及嵌套元素outer liner 都注册了click事件,根据1得出的结论 那么嵌套在最里层的元素liner所占页面的空间范围内 一共有三个click事件作用在其上,那么当在liner元素的作用范围内点击页面时,3个事件的执行顺序会是什么样的呢?

    要解决上面我们提出的问题 这就涉及到了两种处理事件流的不同的机制,事件冒泡 和 事件捕获

    事件冒泡

    IE 的事件流叫做事件冒泡 即事件开始由最具体的元素(文档中嵌套层次最深的节点)接收,然后逐级向上传播到较为不具体的节点。

    示例2:

    将参数设置为false 让元素在冒泡阶段调用事件处理程序:

    我们将CSS代码还改为最开始的时候 ,并修改js代码如下:

    <script>
        var wrap = document.getElementById("wrap");
        var outer = document.getElementById("outer");
        var liner = document.getElementById("liner");
        wrap.addEventListener("click",function(){
            alert("1314");
        },false);
        outer.addEventListener("click",function() {
                alert("1000");
        },false);
        liner.addEventListener("click",function() {
            alert("888");
        },false);
                
    </script    

    当我们只点击橘黄色块的时候 只提示1314 点击淡紫色块的时候 会先弹出1000 在弹出1314 当点击淡蓝色的时候 会依次弹出888, 1000 ,1314 可见冒泡事件是由最具体的元素先接受然后一级一级向上传递(向上传播到不具体的元素)

    结论2:

    在冒泡阶段调用事件处理程序,上面问题的结果是这样的:当点击页面中心浅蓝色的部分时,依次弹出888,1000,1314,因此当容器元素以及嵌套元素都在冒泡阶段调用处理程序时,事件按照冒泡的顺序执行事件处理程序。

    事件捕获

    Netscape团队提出的另外一种事件流叫做事件捕获,事件捕获的思想是 不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件。

    我们将上面的js代码在做一下修改,代码如下,可以看到只是将addEventListener()的第三个参数改为了true

    <script>
        var wrap = document.getElementById("wrap");
        var outer = document.getElementById("outer");
        var liner = document.getElementById("liner");
        wrap.addEventListener("click",function(){
            alert("1314");
        },true);
        outer.addEventListener("click",function() {
                alert("1000");
        },true);
        liner.addEventListener("click",function() {
            alert("888");
        },true);
                
    </script  

    这次 我们再点击浅蓝色的块的时候 会看到先弹出的是 1314 然后是 1000 最后才是自己的事件 弹出 888 是和事件冒泡相反的顺序。是事件捕获的思想

    结论三:

    在捕获阶段调用事件处理程序,上面问题的结果是这样的:当点击页面中心浅蓝色的部分时,先是弹出wrap,接着弹出outer,最后弹出liner。因此当容器元素及其嵌套元素都在捕获阶段调用事件处理程序时:事件按事件捕获的顺序执行事件处理程序。

    问题3:根据思考1,思考2得出的结果,接着又有一个问题我认为需要思考,当同一个元素即在冒泡阶段注册了事件,又在捕获阶段注册了同一事件,那么当事件被触发时,事件的执行顺序又会是如何的?

    要解决问题三 就涉及到了DOM的事件流

    DOM 事件流

    DOM2级事件规定的事件流包括三个阶段:事件捕获阶段-->处于目标阶段-->事件冒泡阶段。首先发生的是事件捕获阶段 为截获事件提供了机会,然后是实际目标接收事件,最后一个阶段是冒泡阶段,以下图片来自w3c

    示例4:

    var wrap = document.getElementById('wrap');
    var outet = document.getElementById('outer');
    var liner = document.getElementById('liner');
    
    wrap.addEventListener('click',function(){
      alert('789');
    },false);
    outer.addEventListener('click',function(){
      alert('456');
    },false);
    inner.addEventListener('click',function(){
      alert('123');
    },false);
    wrap.addEventListener('click',function(){
      alert('wrap');
    },true);
    outer.addEventListener('click',function(){
      alert('outer');
    },true);
    liner.addEventListener('click',function(){
      alert('inner');
    },true);

    结论4:当点击页面中心浅蓝色部分的时候,先从最不具体的节点捕获事件,先弹出wrap,接着弹出outer。接着处于目标阶段,先弹出888,再弹出liner。紧接着,事件处于冒泡阶段,先弹出1000,再弹出1314。因此我们可以得出结论,当容器元素及嵌套元素,即在捕获阶段又在冒泡阶段调用事件处理程序时:事件按DOM事件流的顺序执行事件处理程序,且当事件处于目标阶段时,事件调用顺序决定于绑定事件的书写顺序,按上面的例子为,先调用冒泡阶段的事件处理程序,再调用捕获阶段的事件处理程序

  • 相关阅读:
    命令行添加删除tomcat服务
    访问不到主页index.jsp的原因是servlet-api.jar包有冲突,删除lib的servlet-api.jar,如果报错则添加Apache Tomcat下的 servlet-api.jar 即可。
    在浏览器控制台打印信息
    android访问权限(Android permission )大全
    导入android项目后不自动生成R.java文件的解决方法
    冒泡排序算法
    文本超出div部分,使用省略(...)表示
    sql 连接
    Sprin MVC 4.0中返回 json
    spring boot 配置过程
  • 原文地址:https://www.cnblogs.com/huanying2000/p/6218030.html
Copyright © 2011-2022 走看看