本文主要探讨了JavaScript事件在WebKit中的注冊和触发机制。

JS事件有两种注冊方式: 通过DOM节点的属性加入或者通过node.addEventListener()函数注冊;

通过DOM节点的属性加入例如以下所看到的,节点的属性採用on后面紧接event name的形式,比方onclick, onload;

<html>
<head>
<script type="text/javascript">
function listener(e){
alert("hello world!");
}
</script>
</head>
<body>
<button onclick="listener(event)">click</button>
</body>
</html>

通过addEventListener()函数注冊的形式例如以下, 其完整的形式是:target.addEventListener(type, listener[, useCapture]);当中type为事件类型,listener为响应函数,
useCapture表示是否在capture阶段触发,假设不指定,则为false; 

<div>
<button id="button">button</button>
<script type="text/javascript">
document.getElementById('button').addEventListener("click", listener);
</script>
</div>

WebKit中事件相关的类关系如上图所看到的:

1. EventTargetDatatMap: 全局映射表,建立了Node与EventTargetData之间的映射关系 ;

2. EventTargetData:   成员变量firingEventIterators是Vector, 用于记录正在触发的事件类型,当该Vector非空时。也表示当前正处于firing阶段。 成员变量eventListenerMap是EventlListenerMap类型;

3. EventlListenerMap:按事件类型分类保存了EventListeners;  成员变量m_entires是Vector。当中每一项能够简化为std::pair<EventType, EventListenerVector>类型;

4. JSLazyEventListener: 终于响应事件触发的对象。 保存了JS运行的基本信息(源代码或者JSObject类型的函数对象);

第一种情况下,開始事件注冊的时机是发生在页面解析阶段,当创建了button元素以后。解析到onclick属性时,会依据属性值创建相应的EventListener; 这样的情况下的EventListener仅保存了JS源代码(还没有转换成JSC虚拟机内部的函数对象), 并将EventListener加入到全局Hash表中。

另外一种情况下,JS在虚拟机中运行到”addEventListener()"时。会依据JSBindings建立的映射关系,终于调用到WebCore中的native实现Node::addEventListener(), 该函数会依据虚拟机中传递过来的函数对象创建EventListener。并在全局Hash表中建立起target node与EventListener(即这里的button)的映射关系;

下图是两种情况下,事件注冊的流程对照:

事件触发流程有下面几个步骤:

1. 找到响应事件的target node: 假设是用户交互事件,通过Hit Test算法确定;  假设是浏览器内部生成的事件,一般有固定的响应节点。比方load事件的target node是body节点;

2. 事件分发:事件在document与target之间依照(capture, at_target, bubble)的顺序进行分发,capture依照从根节点document到子节点target的路径,而bubble则相反;

3. 事件响应:分发流程中,假设事件分发到的当前节点注冊了该类型的事件,而且useCapure与事件的分发的顺序一致(即capture阶段时。当前节点注冊了useCapture == true的事件)。 则进行事件响应; 事件响应分成两步: (1) 从全局映射表中找到当前node相应的EventListeners;(2)将EventListeners封装的JS(源代码或者JSC的函数对象)抛到JS虚拟机中运行(下图是mouseup事件的触发时序):

如前所述。属性中注冊的事件在EventListener中仅保存了源代码。所以開始运行之前会对源代码进行必要的转换。格式化成例如以下形式:

      "(function(event) {listener(event)\n})"

简单来讲,事件注冊是建立node与响应函数的映射关系的过程 ,这样的映射关系基于事件类型进行分类。 而事件触发则是基于这样的映射关系,在不同阶段(capture, bubble)响应注冊函数的过程。

(转载请注明出处:http://blog.csdn.net/codigger/article/details/40620721)

JavaScript事件在WebKit中的处理流程研究的更多相关文章

  1. 谈谈JavaScript事件

    众所周知,web前端包含三个基本技术:html.css和javascript.三者融合,才让网页变得精彩纷呈!如今,web上的操作越来越趋于复杂,JavaScript事件在网页中也遍地开花,有时候也是 ...

  2. javascript事件执行流程分析

    我一直想搞清楚事件在DOM中的传播方式,今天经高人指点终于明白一二.首先扒了一张图: 事件捕获过程:当我们点击TEXT时,首先是window->document->body->div ...

  3. webkit中DOM 事件有多少

    webkit中DOM 事件有多少 目前客户端javascript中大量的工作就是处理浏览器,用户触发的各种事件,下面是webkit中这些事件的集合,有一些时常见的,标准规定的,而另一些则是webkit ...

  4. popstate事件在低版本webkit中的调用

    popstate是H5的history系列中的事件,但是在低版本的webkit中会自动触发.H5中的history api是不会使页面发生跳转的,只是操作地址栏和响应的state属性而已,而且是手动操 ...

  5. 浏览器中的JavaScript事件循环机制

    浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...

  6. 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)

    前言 这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅, ...

  7. JavaScript事件详解-jQuery的事件实现(三)

    正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...

  8. Javascript事件模型系列(一)事件及事件的三种模型

    一.开篇 在学习javascript之初,就在网上看过不少介绍javascript事件的文章,毕竟是js基础中的基础,文章零零散散有不少,但遗憾的是没有看到比较全面的系列文章.犹记得去年这个时候,参加 ...

  9. 深入理解JavaScript 事件

    本文总结自<JavaScript高级程序设计>以及自己平时的经验,针对较新浏览器以及 DOM3 级事件标准(2016年8月),对少部分内容作了更正,增加了各种例子及解析. 如无特殊说明,本 ...

随机推荐

  1. Github管理 第二步:Eclipse+Github,管理Java Project版本(First Commit)

    1.提醒 如果你的Eclipse和本文一样操作,却出现了不同的结果和莫名其妙的错误,换个Eclipse也许更快. 我用了2个Eclipse,第一个一步一个坑,第2个非常顺利…… 所以,继Windows ...

  2. Jvm运行时数据区 —— Java虚拟机结构小记

    关于jvm虚拟机的文章网上都讲烂了.尤其是jvm运行时数据区的内容. 抱着眼见为实的想法,自己翻了翻JVM规范,花了点时间稍微梳理了一下. 以下是阅读Java虚拟机规范(Java SE 8版)的第二章 ...

  3. Oracle学习记录1

    1.current_date与sysdate区别 在oracle中current_date与sysdate都是显示当前系统时间, 其结果基本相同,但是有三点区别:a. current_date返回的是 ...

  4. Spring Boot的web开发&静态资源配置方式

    Web开发的自动配置类:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration 1.1. 自动配置的ViewResolve ...

  5. 关于Redux到底是个什么鬼

    原文链接:https://zhuanlan.zhihu.com/p/20641377 我们故事的主人公,小明. 小明大学刚毕业,摆脱了宿舍的集体生活,自己在外面租了个一室一厅的小公寓住. 这是客厅的平 ...

  6. AC日记——线段树练习4 codevs 4919

    4919 线段树练习4  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给你N个数,有两种操作 ...

  7. MySQL创建存储过程/函数需要的权限

    alter routine---修改与删除存储过程/函数 create routine--创建存储过程/函数 execute--调用存储过程/函数 下面有一篇介绍MySQL所有权限的博文 http:/ ...

  8. 【ZJOI2017】树状数组

    题目描述 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的 OI 比赛经历.那是一道基础的树状数组题. 给出一个长度为 $n$ 的数组 $A$,初始值都为 $0$,接下来 ...

  9. DBUtils工具类学习一

    Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能 1.特征 DBUtils是java编程中 ...

  10. IDEA查看源码时提示:Library source does not match the bytecode for class的问题分析

    通过Maven查看依赖的源码时,通常是Maven自动下载JAR包附属的source包,但是会出现一个问题,由于使用lombok插件会造成编写的Java文件和编译后的class上有差别,所以IDEA打开 ...