Javascript与HTML之间的交互是通过事件实现的。
1. 事件流
事件流描述的是从页面中接收事件的顺序。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件流</title>
</head>
<body>
<div id="box"></div>
</body>
</html>
事件冒泡
事件开始 - 具体的元素(文档嵌套层次最深的那个节点)- 逐级向上传播 - 最外围的节点(文档)。
<div> - <body> - <html> - document
事件捕获
事件开始 - 最外围的节点 - 依次向下传播 - 具体的事件节点
document - <html> - <body> - <div>
DOM 事件流: 事件捕获阶段 - 处于目标阶段 - 事件冒泡阶段
document - <html> - <body> - <div> - <body> - <html> - document
IE8及更早的浏览器不支持DOM事件流(不支持事件捕获)
2. 事件处理程序
事件就是用户或者浏览器自身执行的某种动作。 如:‘click’,‘load’,‘mousedown’ 等是事件的名称, 响应事件的函数就是事件处理程序(或者事件侦听器)。
HTML事件处理
<div onclick="alert('点击')">点击我</div>
DOM 0级事件处理程序
<div id="box">点击我</div>
<script type="text/javascript">
var box = document.getElementById('box');
box.onclick = function(){
alert('弹出');
};
</script>
DOM 2级事件处理程序
<div id="box">点击我</div>
<script type="text/javascript">
var box = document.getElementById('box');
box.addEventListener('click', function(){
alert('弹出');
}, false);
</script>
IE8及更早的浏览器的事件处理程序
<div id="box">点击我</div>
<script type="text/javascript">
var box = document.getElementById('box');
box.attachEvent('onclick', function(){
alert('弹出');
});
</script>
兼容的事件处理程序
function addEvent(o, type, fn) {
if (o.addEventListener) {
o.addEventListener(type, fn, false);
} else if (o.attachEvent) {
o.attachEvent('on' + type, fn);
} else {
o['on' + type] = fn;
}
} function removeEvent(o, type, fn) {
if (o.removeEventListener) {
o.removeEventListener(type, fn, false);
} else if (o.detachEvent) {
o.detachEvent('on' + type, fn);
} else {
o['on' + type] = null;
}
}
3. 事件对象
事件会将一个 event 对象传入到事件处理程序中。
<div id="box">点击我</div>
<script type="text/javascript">
var box = document.getElementById('box');
// DOM
box.addEventListener('click', function(event){
alert(event.type);
}, false);
//IE DOM0
box.onclick = function(){
var event = window.event;
alert(event.type);
};
//IE DOM2
box.attachEvent('onclick', function(event){
alert(event.type);
});
</script>
event对象包含与创建它的特定事件有关的属性和方法。
IE的事件对象
4. 事件类型
浏览器中发生的事件有很多种类型,不同的事件类型有不同的信息。
UI事件
load 当页面完全加载后在window上面触发,当所有框架都加载完在框架集上触发,当图像加载完成时在img元素上触发。
unload 当页面卸载后在window上触发,当所有框架都卸载后在框架集上触发
select 当用户选择文本框(input textarea)中的字符时触发
resize 当窗口或框架的大小变化时在window上或框架上触发
scroll 滚动带滚动条的元素的内容时,在该元素上触发 (<body>元素包含所加载页面的滚动条)
焦点事件
焦点事件会在页面获得焦点货失去焦点时触发
blur 元素失去焦点时触发
focus 元素获得焦点时触发
鼠标与滚轮事件
click 单击鼠标主键或者按下回车键时触发
dbclick 双击鼠标主键时触发
mousedown mousemove mouseup
mouseover mouseout
<div id="box">点击我</div>
<script type="text/javascript">
var box = document.getElementById('box');
// DOM
box.addEventListener('click', function(event){
var keys = [];
if(event.ctrlKey){
keys.push('ctrl');
}
if(event.altKey){
keys.push('alt');
}
if(event.shiftKey){
keys.push('shift');
}
alert(keys.join(',')); // 按下了哪些修改键
}, false);
</script>
键盘和文本事件
使用键盘时会触发键盘事件
keydown 按下键盘上的任意键时触发
keypress 按下键盘上的字符键时触发 按住不放会重复触发 Esc键也会触发
keyup 释放键盘上的键时触发
对应键的键码
HTML5事件
contextmenu 上下文菜单
<ul id="box" style="display: none;">
<li>复制</li>
<li>剪切</li>
<li>粘贴</li>
</ul>
<script type="text/javascript">
var box = document.getElementById('box');
document.addEventListener('contextmenu', function(event){
event.preventDefault();
box.style.display = 'block';
}, false);
document.addEventListener('click', function(event){
box.style.display = 'none';
}, false);
</script>
beforeunload 页面卸载前触发
DOMContentLoaded 在DOM树加载完成时触发
readystatechange 提供文档或者元素的加载状态有关的信息
function loadJS(url, callback) {
var doc = document,
script = doc.createElement('script'),
head = doc.getElementsByTagName('head')[0];
script.type = 'text/javascript';
if (script.readyState) {
script.onreadystatechange = function() {
if (script.readyState == 'loaded' || script.readyState == 'complete') {
script.onreadystatechange = null;
callback && callback();
}
};
} else {
script.onload = function() {
callback && callback();
};
}
script.src = url;
head.appendChild(script);
}
hashchange 在URL的参数列表(以及URL中'#'好后面的所有字符串)发生变化时提供通知
触摸事件
touchstart touchmove touchend (iPhone Android)
pointerdown pointermove pointerup (window phone)
手势事件
gesturestart gesturechange gestureen
......
事件委托
自定义事件(事件模拟)
......
第13章主要介绍事件相关知识,事件流,事件处理程序,事件对象,事件类型,事件性能,事件模拟,其中事件性能,事件模拟需要好好熟悉。