JavaScript能够让网站对用户的各种操作及时做出“反馈”,响应用户交互行为,而这些就是:DOM,事件以及事件处理

  • DOM就是操作的元素,这个看《再谈BOM和DOM(1):BOM与DOM概述

  • 事件就是用户或浏览器自身执行的某种动作。比如click,mouseup,keydown,mouseover等都是事件的名字。

  • 事件监听器就是响应某个事件的函数就叫事件处理程序(),事件处理程序以on开头,因此click的事件处理程序就是onclick 或addEventListener

一个完整的事件系统,通常存在以下三个角色:

  • 事件对象,用于储存事件的状态。

  • 事件源对象,当前事件在操作的对象,如元素节点,文档对象,window对象,XMLHttpRequest对象等。

  • 事件监听器,当一个事件源生成一个事件对象时,它会调用相应的回调函数进行操作。在IE中,事件对象恒为全局属性window.event的分身。

DOM0级 事件监听

DOM 0级事件监听:把一个函数赋值给一个事件的处理程序属性

在w3c没有把其DOM 模型引入网页时,netscape与微软已经逼不及待到快他们熟悉的语言中把相关的DOM模型搞进来了。这其实也怪javascript之父忙于把抄袭其他语言,忽略了自身事件系统的建设。从此世界被划分为两大阵营了。

双方都设计两种绑定事件的方法,无侵入式与侵入式。你可以说内联式与非内联式的区别

侵入式:

<input name="ruby" onclick="alert(this.nam)" />

“HTML 的 on- 属性”,违反了 HTML 与 JavaScript 代码相分离的原则,将两者写在一起,不利于代码分工,因此不推荐使用(回顾下下:三层分离——做表现行为结构相分离)。

无侵入式

var btn2=document.getElementById('btn2');//获得btn2按钮对象
btn2.onclick=function(){}//给btn2添加onclick属性,属性又触发了一个事件处理程序

这种是它们都完成了各自的DOM模型,实现对元素节点的索引机制之后的事了。这方面更详细的历程,可参看《javascript事件系统的发展史

为什么没有DOM 史话演绎

Document Object Model的历史可以追溯至1990年代后期微软与Netscape的“浏览器大战”,双方为了在JavaScript与JScript一决生死,于是大规模的赋予浏览器强大的功能。微软在网页技术上加入了不少专属事物,既有VBScript、ActiveX、以及微软自家的DHTML格式等,使不少网页使用非微软平台及浏览器无法正常显示。DOM即是当时蕴酿出来的杰作。

Javascriptd的早期版本向程序员提供了查询和操控Web文档某些实际内容(主要是图像和表单)的手段。因为Javascript预先定义了“images”和“forms”等术语。

在的人们通常把这种试验性质的初级DOM称为“第0级DOM”(DOM Level 0)。在还未形成统一标准的初级阶段,“第0级DOM”的常见用途是翻转图片和验证表单数据。

Netscape和微软公司各自推出第四代浏览器产品以后,(Netscape Navigator 4发布于1997年6月,IE 4发布于1997年10月) ,DOM开始遇到麻烦,陷入困境。NN4和IE4浏览器使用的是两种不兼容的DOM。换句话说,虽然浏览器制造商的目标一样,但他们解决DOM问题时采用的办法却完全不同

就在浏览器制造商以DOM为武器展开营销大战的同时,W3C不事声张的结合大家的优点推出了一个标准化的DOM。令人欣慰的是,Netscape、微软和其他一些浏览器制造商们还能抛开彼此的敌意而与W3C携手制定新的标准,并与1998年10月完成了“第一级DOM”(DOM Level1)

为什么没有DOM0及DOM1 事件

我们的确定标准了是没有DOM0级的。所谓DOM0级只是DOM历史坐标中的一个参照点而已。

具体说来,DOM0级指的是Internet Explorer 4.0和Netscape Navigator 4.0最初支持的DHTML。

在平时阅读的时候可能会读到DOM0级(DOM Level0)的字眼。实际上,DOM0级标准是不存在的,所谓的DOM0级是DOM历史坐标中的一个参照点而已,具体说呢,DOM0级指的是IE4和Netscape 4.0这些浏览器最初支持的DHTML..大概2000年的时候争论过DOM0的问题,最后结论大概是,没有官方形成此标准.。

DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型

这里顺手安利一下《ECMAScript进化史(1):话说Web脚本语言王者JavaScript的加冕历史》、《浏览器史话中chrome霸主地位的奠定与国产浏览器的割据混战

DOM2级 事件处理程序

DOM2开始推崇三层分离:

  1. DOM视图(DOM Views):定义了跟踪不同文档(例如,应用CSS之前和之后的文档)视图的接口;

  2. DOM事件(DOM Events):定义了事件和事件处理的接口;

  3. DOM样式(DOM Style):定义了基于CSS为元素应用样式的接口;

事件与样式 基于 DOM遍历和范围(DOM Traversal and Range):定义了遍历和操作文档树的接口。

DOM3级则进一步扩展了DOM,引入了以统一方式加载和保存文档的方法–在DOM加载和保存(DOM Load and Save)模块中定义;新增了验证文档的方法–在DOM验证(DOM Validation)模块中定义。DOM3级也对DOM核心进行了扩展,开始支持XML 1.0规范,涉及XML Infoset、XPath和XML Base。

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

对于绑定事件,ie低版本的浏览器是用attachEvent,而高版本ie和标准浏览器用的是addEventListener。

attachEvent不能指定绑定事件发生在捕获阶段还是冒泡阶段,它只能将事件绑定到冒泡阶段,但是并不意味这低版本的ie没有事件捕获,它也是先发生事件捕获,再发生事件冒泡,只不过这个过程无法通过程序控制

实事件的兼容性问题特别的多,比如获取事件对象的方式、绑定和解除绑定事件的方式、目标元素的获取方式等等,由于古老的浏览器现在基本被淘汰,所以也没有必要讲了。

事件流

什么是事件流:大白话的说就比如我在页面上点击鼠标右键,这个右键如何反应到页面上,这就是一个事件流的过程

在浏览器相对标准化之前,各个浏览器厂商都是自己实现的事件模型,有的用了冒泡,有的用了捕获,W3C为了兼顾之前的标准,将事件发生定义成如下三个阶段:

  • 捕获阶段 --- 从window元素开始发生,一直到目标元素

  • 目标阶段 --- 事件触发

  • 冒泡阶段 --- 从目前元素开始发生,一直到window元素

事件模型

  • IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素。

  • Netscapte采用事件捕获,先由不具体的元素接收事件,最具体的节点最后才接收到事件。

  • 在dom时代,兼容了二者

addEventListener()和removeEventListener()

在DOM中,addEventListener()和removeEventListener()用来分配和移除事件处理函数,与IE不同的是,这些方法需要三个参数:

  • 事件名称(如click)

  • 要分配的函数(第一个参数Event 对象代表事件的状态)

  • 处理函数是用于冒泡阶段(false)还是捕获阶段(true),默认为冒泡阶段false

[object].addEventListener("name_of_event",fnhander,bcapture)

[object].removeEventListener("name_of_event",fnhander,bcapture)

oDiv.addEventListener("onclick", fnClick, false);  //添加事件处理函数 
oDiv.addEventListener("onclick", fnClickAnother, false);  // 与IE一样,可以添加多个事件处理函数 
oDiv.removeEventListener("onclick", fnClick, false);  //移除事件处理函数

如果使用addEventListener()将事件处理函数加入到捕获阶段,则必须在removeEventListener()中指明是捕获阶段,才能正确地将这个事件处理函数删除

oDiv.onclick = fnClick;  
oDiv.onclick = fnClickAnother;  //使用直接赋值,后续的事件处理函数会覆盖前面的处理函数  oDiv.onclick = fnClick; 
oDiv.addEventListener("onclick", fnClickAnother, false);  //会按顺序进行调用,不会覆盖

指定事件执行阶段

elem.addEventListener("eventType", fn , boolean);

参数说明:

  • 事件类型

  • 函数

  • 如果为true,表示在捕获阶段执行,false为在冒泡阶段执行(默认为false).

阻止事件传播

阻止事件传播,既可以是在冒泡阶段,也可以是在捕获阶段。

有以下方法:

  • e.cancelBubble=true;

  • e.stopPropagation();

  • return false;

e.stopPropagation()阻止事件传播,既可以是在冒泡阶段,也可以是在捕获阶段

e.stopPropagation()很少用到在捕获阶段去阻止事件的传播,大家就以为e.stopPropagation()只能阻止事件在冒泡阶段传播。

阻止默认行为

e.preventDefault()可以阻止事件的默认行为发生,默认行为是指:点击a标签就转跳到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交按钮会提交表单等等,因为有的时候我们并不希望发生这些事情,所以需要阻止默认行为。

DOM3 事件监听

DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件也添加了一些新事件。

DOM中的事件模拟自定义事件

DOM3级还定义了自定义事件自定义事件不是由DOM原生触发的它的目的是让开发人员创建自己的事件。

要创建的自定义事件可以由createEvent("CustomEvent");

JavaScript事件队列

javascript除了主线程,还有一个任务队列的东西,主线程执行完毕了,就去队列找任务,当然我们不点击的话,任务队列就是空的,当我们点击了,addEventLister就会把他的第二个参数的函数放到队列里,然后javaScript主线程突然发现队列里有东西了,就赶紧出栈 出来执行

"任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。

"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。

所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

JavaScript事件处理,就是UI有了操作,就吧相应事件丢到JavaScript执行栈里面。UI交互与JavaScript执行不在同一个线程里面。

比如我们修改DOM,修改dom的操作是JavaScript代码是同步执行的,但是浏览器重排和重绘是异步进行的。

更多此方面的请参看:《同步与异步:并发/并行/进程/线程/多cpu/多核/超线程/管程》、《浏览器层面优化前端性能(2):Reader引擎线程与模块分析优化点》、《弄懂javascript的执行机制:事件轮询|微任务和宏任务|定时器

参考文章:

JavaScript 运行机制详解:再谈Event Loop www.ruanyifeng.com/blog/2014/10/event-loop.html

JS-------DOM0级事件处理和DOM2级事件处理-------简单记法 https://www.cnblogs.com/holyson/p/3914406.html

ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)https://www.cnblogs.com/best/p/8028168.html

JavaScript学习总结(三)BOM和DOM详解 https://segmentfault.com/a/1190000000654274

浏览器事件模型中捕获阶段、目标阶段、冒泡阶段实例详解 https://segmentfault.com/a/1190000003482372

关于DOM级别的一些问题 https://segmentfault.com/a/1190000000366311

再谈BOM和DOM(4):DOM0/DOM2事件处理分析的更多相关文章

  1. js面向对象的学习笔记九(BOM 与 DOM 经常使用的属性分析)

    一  BOM物 window 的 相关属性 1. 用户配置的机器配置对象 navigator navigator.userAgent //该属性能够查看用户机器浏览器的配置 "Mozilla ...

  2. Another Look at Events(再谈Events)

    转载:http://www.qtcn.org/bbs/simple/?t31383.html Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不 ...

  3. JS中的函数、Bom、DOM及JS事件

    本期博主给大家带来JS的函数.Bom.DOM操作,以及JS各种常用的数据类型的相关知识,同时,这也是JavaScript极其重要的部分,博主将详细介绍各种属性的用法和方法. 一.JS中的函数 [函数的 ...

  4. 从零开始的JS生活(二)——BOM、DOM与JS中的事件

    上回书说道,JS中变量.运算符.分支结构.循环和嵌套循环等内容.本回就由本K给大伙唠唠JS中的BOM.DOM和事件. 一."花心大萝卜"--BOM 1.震惊,FFF团为何对BOM举 ...

  5. javascript中DOM0,DOM2,DOM3级事件模型解析

    DOM 即 文档对象模型. 文档对象模型是一种与编程语言及平台无关的API(Application programming Interface),借助于它,程序能够动态地访问和修改文档内容.结构或显示 ...

  6. DOM0,DOM2,DOM3 事件基础知识

    事件是javascript和HTML交互基础, 任何文档或者浏览器窗口发生的交互, 都要通过绑定事件进行交互; 事件有DOM0, DOM2和DOM3的区分(别问我怎么少了一个DOM1, 也没找到DOM ...

  7. DOM0,DOM2,DOM3事件,事件基础知识入门

    事件是javascript和HTML交互基础, 任何文档或者浏览器窗口发生的交互, 都要通过绑定事件进行交互; 事件有DOM0, DOM2和DOM3的区分(别问我怎么少了一个DOM1, 也没找到DOM ...

  8. 实现JavaScript的组成----BOM和DOM

    我们知道,一个完整的JavaScript的实现,需要由三部分组成:ECMAScript(核心),BOM(浏览器对象模型),DOM(文档对象模型). 今天主要学习BOM和DOM. BOM: BOM提供了 ...

  9. DOM0 DOM2 DOM3

    DOM0  DOM2  DOM3 DOM是什么 W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容.结构和样式. DOM 定义了访问 HTML 和 ...

  10. 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

    这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理汇总.如果对文中的题目全部了然于胸,觉得对整个angular框架应该掌握的七七八八了.希望志同道合的通知补充 ...

随机推荐

  1. Python 潮流周刊#26:requests3 的现状

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.本周刊开源,欢迎投稿.另有电报频道作为副刊,补充发布更加丰富的资讯. 品牌赞助 本周刊由"Python猫 ...

  2. LeetCode-Java:88合并两个有序数组

    题目: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目. 请你 合并 nums2 到 nums1 中 ...

  3. MySQL-防止误删除的方案就是删除,看不见岂不就是删除了吗,所以就是把它隐藏起来。

    版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 伪删除: 用update替代delete 1.添加状态列 ALTER TABLE student2 ADD state ...

  4. Vite4+Typescript+Vue3+Pinia 从零搭建(4) - 代码规范

    项目代码同步至码云 weiz-vue3-template 要求代码规范,主要是为了提高多人协同和代码维护效率,结合到此项目,具体工作就是为项目配置 eslint 和 prettier. editorc ...

  5. IDEA:自动生成方法注释并添加 @param 参数(Java+Kotlin)

    在用 Java 或 Kotlin 编写方法时建议编写完善的注释,包含每个参数的意义和返回的内容,下面介绍在 IDEA 中自动生成方法注释的技巧. 第二张图按照图片填写就好了 ③(注意是*不是/*) * ...

  6. 基于win11的Emby、Playnite搭建家庭影音娱乐方案

    0. 概述 0.1 Emby效果 0.2 playnite效果 0.3 软件清单及教程 流媒体:Emby (分Server端.安卓端.安卓TV端.iOS端,PC最好使用网页端) 电影/电视剧/动画:找 ...

  7. 吉特日化MES & HttpClient基础连接已经关闭: 连接被意外关闭

    在吉特日化MES调用某公司AGV平台下发任务的时候,使用HttpClient 进行POST请求,出现如下异常: HttpClient基础连接已经关闭: 连接被意外关闭  , 之前已经使用HTTPCli ...

  8. [ABC263B] Ancestor

    Problem Statement There are $N$ people, called Person $1$, Person $2$, $\ldots$, Person $N$. The par ...

  9. js上传多个文件到asp.net core,并实时转存到阿里云oss

    有时候,为了追求便利性,我们可能会让前端直接将文件上传到阿里云OSS,然后将URL提交给ASP.NET.然而,这种做法意味着前端需要拥有OSS的访问密钥,而将密钥存放在前端,无疑增加了被破解的风险.因 ...

  10. 一个ssh无法远程登录的问题跟踪解决

    用户反馈龙芯服务器系统loongnix-server使用root用户ssh远程登录,有时候可以有时候又无法登录,频繁出现错误:Permission denied,please try again.我分 ...