JavaScript DOM事件模型

更新日期: 2019-03-18阅读: 2.5k标签: dom

早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的dom事件模型及事件处理程序的分类。

1、DOM事件模型。DOM事件模型分为两种:事件冒泡和事件捕获。事件冒泡最初是微软提出的DOM事件流的模型,顾名思义,就是值浏览器的事件流如同冒泡一样,从最低处到最高处。最低处对应的是DOM中最具体的元素,最高处则是最外层元素,最外层元素一般就是document元素。

a、事件冒泡模型:

如下图,当点击最底层的span元素时,在冒泡模型中触发的事件流为:span的click事件触发---->父级元素div的click事件触发---->顶层的document元素的click事件触发。

b、事件捕获模型:

如下图,当点击span元素时,在事件捕获模型中触发的事件流为:最顶层的document的click事件首先被触发---->子容器div(同时也是span的父容器)的click事件被触发

---->最底层的span元素的click事件触发。

可见,事件冒泡和事件捕获的事件触发流程是完全相反的。

2、DOM事件处理程序的分类。DOM事件处理程序分为三种:html事件处理程序、DOM 0级事件处理程序、DOM 2级事件处理程序(注意:、没有DOM1级事件处理程序)。


a、HTML事件处理程序:

指的是事件绑定直接写在HTML上,如:

<input type="button' value="button" onclick="alert('button clicked!')" />
这里button的click事件的绑定直接写在HTML中,这种写法即是HTML事件处理程序。由于这种写法造成HTML和JavaScript的紧耦合,当需要调整JavaScript事件时,不得不调整HTML代码(就算不修改JavaScript函数名,只修改函数的内部实现,仍然不推荐使用这种语法绑定事件,会增加不必要的维护成本)。


b、DOM 0级事件处理程序:

指的是通过给JavaScript对象的事件参数属性赋值的模式,如:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.onclick = function(){
        alert("button clicked!");
    }
</script>

这里通过直接给btnDOM对象的onclick属性赋值的形式来绑定click事件就是DOM 0级事件处理程序,赋值可以使用匿名函数的形式,也可以使用具名函数的形式,如下:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.onclick clickHandle;
    function clickHandle(){
        alert("something clicked!");
    }
</script>

如需注销,只需将该属性设置为null即可,如下:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.onclick clickHandle;
    function clickHandle(){
        alert("something clicked!");
    }
    btn.onclick = null;
</script>

注意:如果绑定使用的是匿名函数的形式,通过给事件属性赋值null仍然可以注销该事件。


c、DOM 2级事件处理程序:

指的是使用 addEventListener("eventName","eventHandle",false),其中eventName表示事件名称、eventHandle表示事件处理函数,false表示是否启用事件捕获模式,默认为false。使用addEventListener函数来给DOM元素绑定事件处理程序,如:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click",function(){
        alert("something clicked!");
    },false);
</script>

同样,这里既可以使用匿名函数的形式也可以使用具名函数的形式,如:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click",clickHandle,false);
    function clickHandle(){
        alert("something clicked!");
    }
</script>

注意:通过addEventListener绑定的事件只能通过removeEventListener来注销,不能使用DOM 0级中的方式注销事件处理程序,注销事件如下:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click",clickHandle,false);
    function clickHandle(){
        alert("something clicked!");
    }
    btn.removeEventListener("click",clickHandle);
</script>

如果绑定时使用的是匿名函数,则注销操作比较麻烦,可以通过事件参数的callee属性获取当前正在执行的函数,但必须使用在事件绑定的函数内,如:

<script>
    var dom=document.getElementById("content");
    var clickNum=0;
    dom.addEventListener("click",function(e){
    clickNum++;
    alert('你摸了我'+clickNum+'下了。最多摸2下哦');
    if(clickNum>=2){
        dom.removeEventListener(e.type,arguments.callee,false);
        console.log(this);
    }
});
</script>


d、IE中DOM 2级事件处理程序的是通过attachevent来绑定的,语法与addEventListener完全一致。

 

e、DOM 0级和DOM 2级事件处理程序的主要区别:

DOM 2级事件处理程序可以给元素的事件绑定多个处理程序,如:

<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click",clickHandle1,false);
    btn.addEventListener("click",clickHandle2,false);
    function clickHandle1(){
        alert("something clicked!");
    }
    function clickHandle2(){
        alert("something clicked again!");
    }
</script>
此时,点击btn时将会依次触发clickHandle1、clickHandle2,注销事件处理程序也需要针对每个事件处理程序使用removeEventListener。
DOM 0级事件处理程序如果以这种形式绑定事件,则后写的方法会覆盖掉之前的方法,即:
<input id="btn" type="button" value="button" />
<script>
    var btn = document.getElementById("btn");
    btn.onclick = clickHandle1();
    btn.onclick = clickHandle2();
    function clickHandle1(){
        alert("something clicked!");
    }
    function clickHandle2(){
        alert("something clicked again!");
    }
</script>

这里实际只会绑定clickHandle2方法,clickHandle1被后面的clickHandle2覆盖掉。

 

开发过程中推荐使用DOM 0级事件处理程序或者DOM 2级事件处理程序,如果只有一个事件处理程序DOM 0级就足够了,当然,如需绑定多个事件处理程序,则需使用DOM 2级事件处理程序。

为了屏蔽各浏览器之间的实现差异,推荐使用一些JavaScript库来辅助完成事件绑定。推荐使用jquery,针对不同的浏览器,可以使用统一的接口来完成这一过程。


链接: https://www.fly63.com/article/detial/2431

全面理解虚拟DOM,实现虚拟DOM

DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的。虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。

HTML文档解析和DOM树的构建

浏览器解析HTML文档生成DOM树的过程,以下是一段HTML代码,以此为例来分析解析HTML文档的原理.解析HTML文档构建DOM树的理解过程可分为两个主要模块构成,即标签解析、DOM树构建

原生js获取DOM对象的几种方法

javascript获取DOM对象的多种方法:通过id获取 、通过class获取、通过标签名获取、通过name属性获取、通过querySelector获取、通过querySelectorAll获取等

js实现DOM遍历_遍历dom树节点方法

遍历DOM节点常用一般用节点的 childNodes, firstChild, lastChild, nodeType, nodeName, nodeValue属性。在获取节点nodeValue时要注意,元素节点的子文本节点的nodeValue才是元素节点中文本的内容。

如何编写自己的虚拟DOM

要构建自己的虚拟DOM,需要知道两件事。你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂——但实际上,虚拟DOM的主要部分只需不到50行代码。

归纳DOM事件中各种阻止方法

事件冒泡: 即事件开始时由最具体的元素(文档中嵌套层数最深的那个点)接收,事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件.与此同时,我们还需要了解dom事件绑定处理的几种方式:

关于DOM操作是异步的还是同步的相关理解

先列出我的理解,然后再从具体的例子中说明:DOM操作本身应该是同步的(当然,我说的是单纯的DOM操作,不考虑ajax请求后渲染等);DOM操作之后导致的渲染等是异步的(在DOM操作简单的情况下,是难以察觉的)

vuejs2.0如何获取dom元素自定义属性值

设置定义属性值 :data-value=.., 2.直接获取 3.通过this.$refs.***获取 1.目标DOM定义ref值: 2.通过 【this.$refs.***.属性名】 获取相关属性的值: this.$refs.*** 获取到对应的元素 ...

整理常见 DOM 操作

框架用多了,你还记得那些操作 DOM 的纯 JS 语法吗?看看这篇文章,来回顾一下~ 操作 className,addClass给元素增加 class,使用 classList 属性

浏览器中的JavaScript:文档对象模型与 DOM 操作

JavaScript 并没有那么糟糕。作为运行在浏览器中的脚本语言,它对于网页操作非常有用。在本文中,我们将看到可以用哪些手段来修改 HTML 文档和交互。文档对象模型是在浏览器中一切的基础。但它究竟是什么呢?

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!