JS权威指南读书笔记(七)
第十七章 事件处理
1 客户端JS程序采用了异步事件驱动编程模型。
2 关于事件的重要定义
a 事件类型(event type)
b 事件目标(event target) target === srcElement(IE8及之前版本)
c 事件处理程序(event handler ) 当对象上注册的事件处理程序被调用时,可以说浏览器触发(fire trigger)和派发(dispatch)了事件;
d 事件对象(event object)
e 事件传播(event propagation)两种形式:捕获和冒泡
f 事件取消:可以通过返回一个适当的值,调用事件对象的某个方法或设置事件对象的某个属性来阻止默认操作的发生。
3 事件的来源,除了传统事件以外
a 3级DOM事件
b HTML5规范及相关衍生规范定义大量API
c 基于触摸和支持JS移动设备
4 无论用户何时输入文字(通过键盘或剪切和粘贴)到文本输入表单元素中,都会触发input事件(IE11已兼容)。
5 window事件,在document监听(document.addEventListener...)
a DOMContentLoaded 当文档和其元素为操作准备就绪,但外部资源完全加载完毕之前;
b readystatechange
c load 当文档和其所有外部资源完全加载并显示给用户时触发它;
d beforeunload 提供询问用户是否确定离开当前页面的机会;
e unload 当用户离开当前文档转向其他文档时触发它
6 当keydown事件产生可打印字符时,在keydown和keyup之间会触发另外一个keypress高级事件。
7 clientX 和 clinetY 属性指定了鼠标在窗口坐标中的位置,button 和 which 属性指定了按下的鼠标键是哪个。
8 3级DOM事件标准化了不冒泡的focusin 和 focusout事件来取代冒泡的focus 和 blur事件,标准化了冒泡的 mouseenter 和 mouseleave 事件来取代不冒泡的mouseover 和 mouseout 事件。
9 HTML5事件
a 音视频事件
b 拖放API
c 历史管理机制,允许Web应用同浏览器的返回和前进按钮交互,涉及的事件是hashchange 和 popstate,在window上触发;
d 离线Web应用支持,offline 和 online,失去或得到网络时,在window上触发。
e 跨文档通信API,message事件
f XMLHttpRequest规范第二版和File API规范,定义了一系列事件来跟踪异步 I/O 的进度(loadstart, progress, loadend);
10 触摸屏和移动设备事件
a 用户旋转 orientationchange 事件
b 高级手势事件 gesturestart gesturechange gestureend(事件参数 scale 和 rotation)
c 初级手势事件 touchstart touchmove(点击不会触发) touchend,当点击时触发事件的顺序:touchstart touchend mouseover mousemove mousedown mouseup click;
11 注册事件处理程序的两种方式
a 给事件目标对象或文档元素设置属性(ele.onclick = ... 或 在html中 onclick = ...);
b 将事件处理程序传递给对象或元素的一个方法(addEventListener 或 attachEvent)。
12 addEventListener:当对象上发生事件时,所有该事件类型的注册处理程序都会按照注册的顺序调用(即注册多次click事件,不同的处理程序,所有的处理程序按注册顺序执行)。使用相同的处理程序(即注册多次click事件,同一个处理程序,只执行一次)多次调用addEventListener是没用的,处理程序仍然只注册一次。
13 addEventListener 和 attachEvent 区别
a IE事件模型不支持事件捕获,所以attachEvent 和 detachEvent 要求只有两个参数:事件类型和处理程序函数;
b attachEvent第一个参数使用带"on" 前缀的事件类型,而addEventListener则使用不带"on"前缀的;
c attachEvent 允许相同的事件处理程序函数注册多次,当特定事件类型发生时,注册函数的调用次数和注册次数一样。
14 在IE8及以前版本中,通过设置属性注册事件处理程序时,当调用时并未传递事件对象,需要通过全局对象window.event 来获得事件对象;向使用attachEvent 注册的事件处理程序传递事件对象,但它们也能使用window.event。
15 当通过设置HTML属性注册事件处理程序时,浏览器会把JS编码转换到一个函数中。非IE浏览器使用event参数来构造函数,而IE在构造函数时没有要求函数。
16 事件处理程序的执行上下文
a 通过设置属性注册事件处理程序,e.onclick = ...,this关键字指的是事件目标,处理程序作为这个对象的方法;
b 使用addEventListener,事件目标作为this;
c 使用attachEvent,全局对象window作为this;
17 处理程序的作用域是其定义时的作用域,而非调用时的作用域;但是通过HTML属性来注册事件处理程序是一个例外,它们被转换为能存取全局变量的顶级函数而非任何本地变量,因为历史原因,它们运行在一个修改后的作用域链中,可以像本地变量一样使用目标对象和Document对象的属性(比如用tagName替换this.tagName),HTML事件处理程序中修改的作用域链是陷阱之源。
18 通常情况下,返回值false就是告诉浏览器不要执行这个事件的默认操作。比如,输入域上的onkeypress事件处理程序通过返回false来过滤键盘输入。注意:理解事件处理程序的返回值只对通过属性注册的处理程序才有意义。
19 取消事件,addEventListener 和 attachEvent注册事件处理程序转而必须调用preventDefault() 方法或设置事件对象的returnValue(非标准的)属性。
20 文档元素或其他对象可以为指定事件类型注册多个事件处理程序,当适当的事件发生时,调用顺序如下:
a 通过设置对象属性或HTML 属性注册的处理程序(更优先)优先调用
b 使用addEventListener注册的处理程序按照它们的注册顺序调用
c 使用attachEvent注册的处理程序可能按照任何顺序调用。
21 事件的三个阶段(一段时间的延续):捕获 目标(目标本身的事件处理程序调用是第二个阶段) 冒泡
22 stopPropagation:该方法将停止事件的继续传播,阻止它被分派到其他document节点。在事件传播的任何阶段都可以调用它。注意:虽然该方法不能阻止本身节点上其他事件句柄被调用,但是它可以阻止把事件分派到其他节点。
23 IE9之前不支持stopPropagation,不过可以通过设置event对象的cancelBubble属性阻止传播。
24 当前的DOM事件规范草案在Event上定义另一个方法,stopImmediatePropagation(),这个方法阻止了任何其他对象的事件传播,但也阻止了在本省对象上注册的任何其他事件处理程序。
第十八章 脚本化HTTP
1 可以实现Ajax请求的标签:img script iframe
2 使用HTTP API第一件事,实例化XMLHttpRequest对象,如果重用已存在的XMLHttpRequest,将会终止之前通过该对象挂起的任何请求。
3 HTTP协议组成三部分
a 请求行(方法 & 地址) 消息报头 请求正文
b 响应行(版本 & 状态码 & 错误说明) 消息报头 响应正文
4 浏览器需要考虑cookie、重定向、缓存和代理等等。
5 request.open()
a 第一个参数指定方法 GET POST,不区分大小写
b 第二个参数是URL,请求的主题;
c 第三个参数是布尔值,决定是否异步请求(当传入false时,作为同步请求)
d 第四个和第五个参数,对于需要账户的密码的地址,传入用户名和密码
6 request.setRequestHeader()
如果有请求头的话,请求进程的下一步就是设置它,如果对相同的头调用多次,新值不会取代之前指定的值,相反,HTTP请求将包含这个头的多个副本或这个头将指定多个值。另外,不能自己指定,"Content-Length"、"Date"、"Referer" 或 "User-Agent"头,XHR将自动添加这些头而防止伪造它们;类似地,XMLHttpRequest对象自动处理cookie、字符集和编码判断等;
7 request.send() 指定可选的请求主体并向服务器发送它。
8 响应主体可以从responseText属性得到文本,可以从responseXML 属性得到Document形式的。
9 request.open -> request.setRequesHeader -> request.send,必须按照顺序执行,同时监听XMLHttpRequest上readystatechange事件。
10 服务器响应的正常解码是假设服务器为这个响应发送了"Content-Type"头和正确的MIME类型。如果服务器发送XML文档但没有设置适当的MIME类型,XMLHtppRequest对象将不会解析它并设置responseXML属性;或者服务器在"Content-Type" 头中包含了错误的"charset" 参数,那么XMLHttpRequest将使用错误的编码来解析响应,并且responseText中的字符可能是错的。XHR2定义了overrideMimeType() 方法来解决这个问题。在调用send之前,将类型传递给overrideMimeType(),这将使XMLHttpRequest忽略"Conten-Type"头而使用指定的类型。假设你要下载XML文档,而你计划把它当作文本来对待。可以使用overrideMimeType() 来更改类型处理。
request.overrideMimeType("text/plain;charset=utf-8")。
11 编码请求主体(即send的参数):
a 表单编码的请求,对每个表单元素的名字和值执行普通的URL编码,使用等号把编码后的名字和值分开,并使用&分开键值对;正式的MIME类型,application/x-www-form-urlencoded;当使用POST方法提交表单数据时,必须设置"Content-Type"请求头为这个;
b JSON编码的请求,使用JSON.stringify() 编码请求主体
c XML编码的请求,XMLHttpRequest的send方法的参数是一个字符串或null,但是也可以传入XML Document对象,此时不设置"Content-Type"也是可以的;
d 上传文件,XHR2允许send() 方法传入任何的Blob对象
e multipart/form-data 请求,同时包含文件上传元素和其他元素时,则必须使用这个编码来提交表单;这种编码包括使用长"边界"字符串把请求主体分离成多个部分。注意:XHR2 定义了新的FormData API,它容易实现多部分请求主体。首先,使用FormData构造函数创建FormData对象,然后按需多次调用append() 方法添加个体(字符串、File 或 Blob对象)到请求中。最后,把这个对象传递给send方法,send方法将对请求定义合适的边界字符和设置"Content-Type".
12 Http进度事件,当正在加载服务器的响应时,XHR对象对发生progress事件,通常每隔50毫秒左右,所以可以使用这些事件给用户返回请求的进度。如果请求快速完成,它可能从不会触发progress事件。当事件完成,会触发load事件。与progress事件相关联的事件对象还有3个有用的属性,loaded属性是目前传输的字节数值,total属性是传输数据的整体长度(单位是字节),如果知道内容长度,lengthComputable属性为true。
13 Http请求无法完成
a 请求超时,会触发timeout事件
b 请求中止,会触发abort事件
c 网络错误阻止请求完成,会触发error事件
14 XHR2规范草案指出,一旦这些事件中的一个发生后,浏览器应该触发loadend事件。
15 上传进度事件,XHR2给出了用于监控HTTP请求上传的事件。XHR对象将有upload属性,是一个对象,包含了回调接口。
16 可以通过XHR对象的abort() 方法来取消正在进行的HTTP请求。
17 XHR2通过在HTTP响应中选择发送合适的CORS允许跨域访问网站。
18 实现CORS跨域的安全细节:
a 首先,如果给XHR的open方法传入用户名和密码,它们绝对不会通过跨域请求发送;
b 其次,跨域请求通常也不会包含其他任何的用户证书:cookie和HTTP身份验证令牌(token)通常不会作为请求的内容部分发送且任何作为跨域响应来接收的cookie都会丢弃。如果跨域请求需要这几种凭证才能成功,那么必须在用send() 发送请求前设置XHR的withCredentials属性为true。
c 最后,测试withCredentials的存在性是测试浏览器是否支持CORS的一种方法。
19使用script元素作为Ajax传输的技术称为 JSONP,P代表“填充”或“前缀”
a script标签不受同源策略影响
b 包含JSON编码数据的响应体会自动解码即执行
20 使用JSONP,响应数据是合法的JS代码,当它到达时浏览器将执行它。相反,不使用JSONP,而是对JSON编码过的数据解码,结果还是数据,并没有做任何事情。这就是P的意义所在,当通过script元素调用数据时,响应内容必须用JS函数名和圆括号包裹起来。
21 服务端推送事件,客户端创建一个EventSource对象时,会建立一个到服务器的连接,服务器保持这个连接处于打开状态。当发生一个事件时,服务器端在连接中写入几行文本。