zoukankan      html  css  js  c++  java
  • DOM事件模型

    事件

    参考:

    W3C链接

    了解DOM 事件模型

    DOM 事件详解

    事件捕获、事件冒泡以及事件代理

    原生JavaScript和Vue、小程序都是如何阻止事件冒泡的?


     

    DOM事件级别


     

    1 事件流

    事件流描述的是从页面中接受事件的顺序。

    1.1 事件冒泡

    IE 的事件流叫事件冒泡,即事件开始时由最具体的元素接受,然后逐级向上传播到较为不具体的节点(文档),Chrome,Firefox和Safari会将事件一直冒泡到 window 对象。

    1.2 事件捕获

    Netscape Communicator 团队提出的另一种事件流叫做事件捕获。事件捕获的思想是不太具体的节点应该更早接受到事件,而最具体的节点应该最后接收到事件。事件捕获的用以在于事件到达预定目标之前捕获它。一般从document对象开始传播,用的较少。

    1.3 DOM事件流

    Graphical representation of an event dispatched in a DOM tree using the DOM event flow

    上图是W3C标准的DOM事件流模型图。

    “DOM2级事件” 规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。


    2 事件处理程序

    前面说的是事件,事件就是用户或浏览器自身执行的某种动作。如:click是事件的名字,事件处理程序就是onclick。为事件指定处理程序的方式有好几种

    2.1 HTML 事件处理程序

    其实就是,HTML 的on属性

    <button onclick="doxxx()">点击</button>

    使用这个方法指定的监听代码只会在冒泡阶段触发。

    2.2 DOM0 级事件处理程序,缺点:无法设置多个事件处理函数

    元素节点的事件属性。

    let btn = document.getElementById("myBtn:);
    btn.onclick = function () {
        alert("Clickes")      
    }

    如果想删除只需:btn.onclick = null;  // 删除事件处理程序

    2.3 DOM2 级事件处理程序,可以为事件设置多个事件处理函数,可以通过第三个参数 ( useCapture ) 设置在什么阶段执行事件处理函数,默认是 false, 即在事件冒泡阶段执行事件处理函数。

    DOM2级事件定义了两个方法,用于处理指定 和 删除事件处理程序的操作:addEventListener()removeEventListener()

    所有DOM节点中都包含这两种方法。并且都接受三个参数:要处理的事件名作为事件处理程序的函数一个布尔值(默认false表冒泡)

    (1)EventTarget.addEventListener()

    function print() {
      console.log('Print Hello world');
    }
    
    var btn = document.getElementById('btn');
    btn.addEventListener('click', print, false);

    上面代码的意思就是,节点id为btn的元素,使用addEventListener方法绑定click事件,点击的时候会监听函数print会发生。另外,因为useCapture设置为false,所以该函数只在冒泡阶段触发
    当我们需要添加多个不同的监听函数,使用addEventListener非常棒,遵从先添加先触发原则,而且不小心在同一个事件重复添加了同一个函数,它还会自动移除,该函数只会执行一次。

    (2)EventTarget.removeEventListener()
    顾名思义,用来移除addEventListener方法添加的事件监听函数。
    它的参数和addEventListener方法一致,而且写的时候要一一对应。要做到三同,一是在同一个元素节点,二是同一个监听函数,三是第三个参数要一致。

    2.4 IE 事件处理程序

    (1)事件绑定监听函数:attachEvent(eventType, listener)
    (2)事件移除监听函数:detachEvent(eventType, listener)


    3 事件对象

    3.1 DOM 中的事件对象

    事件发生的时候,会将一个 event 对象传入到事件处理程序中,从而可以使用对象的属性和方法。我随意列出几个。
    bubbles:返回一个布尔值,表示当前事件是否会冒泡。该属性为只读属性
    cancelable:返回一个布尔值,表示事件是否可以取消。该属性为只读属性
    currentTarget:事件处理程序当前正在处理事件的那个元素
    preventDefault():取消事件的默认行为。如果 cancelable 是true,则可以使用这个方法
    stopPropagation():取消事件的进一步捕获或冒泡。如果 bubbles为 true,则可以使用这个方法。
    事件处理程序使用DOM0 级或是 DOM2 级,都会传入 event 对象,这个我们不用care。
    var btn = document.getElementById("myBtn");
    btn.onclick = function(event){
          console.log(event.type);    //"click"
      };
    btn.addEventListener("click", function(event){
          console.log(event.type);    //"click"
      }, false);
    <button onclick="console.log(event.type)()">点击</button>

    3.2 IE中的事件对象

    与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于指定事件处理程序的方法。

    (1) HTML 事件处理程序

    <button onclick="console.log(event.type)()">点击</button>

    (2) DOM0 级事件处理程序

    let btn = document.getElementById("btn");
    btn.onclick = function(){
     var event = window.event;
     console.log(event.type);     //"click"
    };

    (3) DOM2 级事件处理程序

    let btn = document.getElementById("btn");
    btn.attachEvent("onclick", function(event){
     console.log(event.type);         //"click"
    });

    4 事件类型(DMO3 级事件规定了以下几类事件)

    DOM3 级事件是在 DOM2 级事件的基础上添加了更多的事件类型,允许自定义事件。

    • UI事件,当用户与页面上的元素交互时触发,如:load、scroll
    • 焦点事件,当元素获得或失去焦点时触发,如:blur、focus
    • 鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
    • 滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
    • 文本事件,当在文档中输入文本时触发,如:textInput
    • 键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
    • 合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
    • 变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified

    如何阻止冒泡

    例子:

    <div onclick="alert('最外层')">
        <div onclick="alert('中间层')">
            <a id="ahref" href="http://www.javanx.cn" onclick="alert('最里层')">点击我</a>
        </div>
    </div>

    点击:点击我 --》最里层 --》中间层 --》最外层 --》然后转跳链接。这就是冒泡。

    1.JavaScript 中

    event.stopPropagation()  // propagation: 传播
    $(function() {
        $("#ahref").click(function(event) {
            event.stopPropagation();
        });
    });

    点击:点击我 --》 最里层 --》转跳链接  事件处理过程中,阻止了事件冒泡,但不会阻击默认行为(执行了超链接的跳转)

    return false

    $(function() {
        $("#ahref").click(function(event) {
            return false;
        });
    });

    点击:点击我 --》 最里层 --》但不会转跳链接  事件处理过程中,阻止了事件冒泡,也阻止了默认行为(没有执行超链接的跳转)

    event.preventDefault()

    $(function() {
        $("#ahref").click(function(event) {
            event.preventDefault()  
        });
    });

     点击:最里层 --》中间层 --》最外层,但最后没有转跳  不能阻止事件冒泡,但阻止了默认行为。

    2.Vue 解决事件冒泡

    Vue.js 提供了事件修饰符,我们只需要添加 click.stop 即可预防事件冒泡

    <div @click="cancelSelect">
        <div class="picker_alert" @click.stop>
            <div class="ofh">
                <span @click="toRoomManagement">编辑</span>
                <span @click="confirmRoom">确定</span>
            </div>
        </div>
    </div>

    Vue修饰符:.stop, .prevent, .capture, .self, .once

    <!-- 阻止单击事件冒泡 -->
    <a v-on:click.stop="doThis"></a>
     
    <!-- 提交事件不再重载页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
     
    <!-- 修饰符可以串联 -->
    <a v-on:click.stop.prevent="doThat"></a>
     
    <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
     
    <!-- 添加事件侦听器时使用事件捕获模式 -->
    <div v-on:click.capture="doThis">...</div>
     
    <!-- 只当事件在该元素本身(比如不是子元素)触发时触发回调 -->
    <div v-on:click.self="doThat">...</div>

    提示:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
    因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止元素上的点击。
     
  • 相关阅读:
    fastjson 解析 字符串 为对象
    fastjson 对类模板进行 parseObject
    VUE路由跳转传递参数的几种方式
    ES 常用设置修改
    springboot图片路径形式获取图片
    Elasticsearch根据ID进行查询
    linux 常用命令
    Elasticsearch常用操作
    java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch
    logstash数据迁移
  • 原文地址:https://www.cnblogs.com/CZheng7/p/13565306.html
Copyright © 2011-2022 走看看