谈谈DOM0,DOM1,DOM2,DOM3

DOM (Document Object Model)文档对象模型

关于JS事件

  • JS程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的对应事件被触发,那么添加的事件监听函数就会被调用。
  • 事件是JS和HTML交互的基础,任何文档或者浏览器窗口发生的交互,都要通过绑定事件进行交互。
  • 所有浏览器都支持DOM0级的事件处理程序,使用该方式时,事件处理都是在元素的作用域中运行,因此程序中的this都是指向该元素。

什么是DOM0,1,2,3 ?

在W3C协会制定的DOM标准中,DOM标准可以分为DOM1,DOM2,DOM3三个版本。

事实上,DOM0级标准是不存在的,所谓DOM0只是DOM历史坐标中的一个参照点。

  • DOM1主要定义的是HTML和XML文档的底层结构
  • DOM2和DOM3分别在这个结构的基础上引入更多的交互能力,例如扩展API,也支持了更高级的XML特性

DOM0

一开始浏览器处理事件的时候只有原始事件模型,例如直接在HTML标签上绑定事件onclick

<input id="myButton" type="button" value="Press Me" onclick="alert('thanks');">

或者获取DOM节点后绑定事件

document.getElementById("myButton").onclick = function () {
    
    
        alert('thanks');
}

在js中html元素都有一个对应的对象,这个对象的属性对应那个html元素的性质,所以可以用js代码添加事件监听函数。

无论用html还是js,都是把一个函数赋值给文档元素,在事件监听函数被调用时候它是作为产生事件的元素的放法调用的,所以this引用的是那个目标元素(例子中的Input对象)。

DOM1

DOM1级于1998年10月1日成为W3C推荐标准。

DOM1标准中并没有定义事件相关的内容,所以没有所谓的DOM1事件模型

DOM2

DOM2中,当事件发生在节点时,目标元素的事件处理函数被触发,并且事件传播分为三个阶段进行。即捕获阶段、事件处理阶段、冒泡阶段

在这里插入图片描述

  • 在捕获阶段,事件从DOM对象沿着文档树向下传播给节点。如果目标的任何一个父元素注册了事件监听函数,那么事件传播的过程中就会运行这些函数
  • 在事件处理阶段,运行注册在目标节点上的事件监听函数
  • 在冒泡阶段,事件将从目标元素向上传播回DOM对象(与捕获阶段相反)。

事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含所有与事件相关的信息。

DOM2注册和销毁事件监听函数

DOM2事件模型中,通过调用对象的addEventListner()方法为元素设置事件监听函数,即只有通过这个API注册的函数才能在触发上述事件传播的三个阶段。

addEventListener参数

  • 第一个参数为String类型,是调用事件的名称,与DOM0级不同的是不需要前缀on,例如要注册click事件就传入click而不是onclick
  • 第二个参数是回调函数,在调用的时候JS回传给函数一个event对象,这个对象包含有关事件的所有细节,如果调用这个对象的stopPropagation()方法,则会组织事件进一步传播。
  • 第三个参数为boolean类型,true表示事件监听函数能够在三个阶段中的任何一个阶段捕捉到事件,false表示事件监听函数不能再捕获阶段捕获到事件(表现同DOM0)。

使用removeEventListener()方法来删除事件处理程序。

DOM2中的event对象

  • type:发生的事件的类型,例如"click", “mouseover”
  • target:发生事件的节点,可能与currentTarget不同
  • currentTarget:正在处理事件的节点,如果在capturing阶段和冒泡阶段处理事件,这个属性就与target属性不同。在事件监听函数中应该用这个属性而不是this
  • stopPropagation():可以阻止事件从当前正在处理他的节点传播
  • preventDefault():阻止浏览器执行与事件相关的默认动作,与0级DOM中返回false一样
  • clientX, clientY:鼠标相对于浏览器的x坐标y坐标
  • screenX, screenY:鼠标相对于显示器左上角的x坐标y坐标

DOM0和DOM2的区别

DOM0注册的事件处理函数会被覆盖

    <button id="btn" onclick="console.log(111)">按钮</button>
    <script>
        const btn = document.getElementById("btn")
        btn.onclick = () => {
    
    
            console.log(222)
        }
    </script>

如上的代码中,使用两种DOM0的方法给同一元素绑定了click事件
事实上,当点击按钮时,只会打印222,因为后注册的函数覆盖了之前的处理函数。

DOM2注册的事件处理函数不会被覆盖,会按顺序依次执行

    <button id="btn" onclick="console.log(111)">按钮</button>
    <script>
        const btn = document.getElementById("btn")
        btn.onclick = () => {
    
    
            console.log(222)
        }
        btn.addEventListener("click",()=>{
    
    
            console.log(333)
        })
        btn.addEventListener("click",()=>{
    
    
            console.log(444)
        })

执行结果如下

在这里插入图片描述

可以看出,同一元素上,DOM2绑定的事件不会影响DOM0绑定的事件,并且DOM2事件不会被覆盖。

DOM0使用局限大

DOM0注册的事件,HTML与JS代码紧密耦合,若要更换事件处理程序,则需要改动HTML和JS两处的代码。

DOM0同一事件只能触发一种事件处理程序(因为会被覆盖),DOM2可以添加多个事件处理程序。

删除事件处理程序的方法不同

若要删除事件处理程序,

  • DOM0只需要btn.onclick = null
  • DOM2需要使用removeEventListener方法

DOM3

DOM3事件在DOM2事件的基础上添加了更多的事件类型

在这里插入图片描述
同时DOM3事件也允许开发人员自定义事件

猜你喜欢

转载自blog.csdn.net/Dax1_/article/details/125979189