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章主要介绍事件相关知识,事件流,事件处理程序,事件对象,事件类型,事件性能,事件模拟,其中事件性能,事件模拟需要好好熟悉。