事件本质: 交互瞬间。
事件表示:每个事件都由基于Event 接口的一个对象表示
UI事件
定义:不一定与用户操作有关的。。呸。。
load事件:要想向DOM中添加一个新元素,就得确定页面加载完毕,因为防止在页面加载完毕前操作 document.body 导致错误。
window/document?
img:
12document.body.appendChild(image);image.src = "smile.gif"; // 新图像元素只要设置了 src 属性就开始下载,
unload:在文档被完全卸载后触发,一般利用于清除引用,避免内存泄漏
resize:The document view has been resized.(window对象上发生)
scroll:The document view or an element has been scrolled.(window对象上发生)
焦点事件
focus:元素获得焦点(不会冒泡
blur:元素失去焦点(不会冒泡
鼠标与滚轮事件
click:在元素上按下并释放任意鼠标按键、回车键
mousedown:在元素上按下任意鼠标按钮
mouseup:在元素上释放任意鼠标按键
|
|
- dbclick:在元素上双击鼠标按钮1双击事件:mousedown -> mouseup -> click -> mousedown -> mouseup -> click -> dbclick
- mouseout: 指针移出元素,或者移到它的子元素上
mouseover:指针移到有事件监听的元素或者它的子元素内
- 区别:out呢,是 target 元素是本身, relatedTarget 是别的元素。 over 正相反。
鼠标坐标:
视图窗口:event.clientx
页面: event.pageX
屏幕:event.screenX
修改键:
- event.shiftKey、ctrl、alt
鼠标按钮:button 属性值。左右键:1/2/0
鼠标滚轮:mousewheel
- event.wheelDelta(+、-用来判断方向,数值不用关心)
触摸设备:移动端以后再看。
键盘与文本事件
虽然所有元素都支持,但一般用户通过文本框输入才使用。
keydown:按下任意按键
keypress:除 Shift, Fn, CapsLock 外任意键被按住. (连续触发)
- keyup:释放任意按键
input:
变动: input
以下描述全部废弃
跟keypress 区别是:一是只有可编辑区域才能出发。二是只有在用户按下能够输入实际字符的键才会被触发。
因此主要考虑是字符,可以通过 evnet.data 获取用户输入的字符而非字符编码。换句话说,用户在没有按上档键情况下按 s 键,data 值就是 “s”,按下上档键后就是 “S”. 懵逼
- 键码:envet.keycode 。它属性的值与 ASCII 码中对应小写字母或者数字的编码相同。而其他非字符键的键码有图。。
变动事件
!昨晚才看的变动事件,今天在 msn 上看时已经被废弃了,改用 MutationObserver 方案。过了5年变动就这么大了。
HTML5事件
contextmenu:右键菜单
beforeunload:window,document 及其资源即将被卸载。
- DOMContentLoaded: 废弃
- hashchange vs location : URL has changed
- readystatechange(跳过)
- pageshow/pagehide(跳过)
内存和性能
背景:在 js 中,添加到页面上的事件处理程序都将直接关系到页面的整体性能。导致这问题有两点原因:一是每个函数都是对象,都会占用内存,内存的对象越多,性能越差。二是必须提前指定所有事件处理程序而导致DOM 访问次数增加,会延迟整个页面的交互就绪时间。
事件委托
- 做法简单来说:只指定一个事件处理程序,就可以管理某一类型的所有事件。比如说 click 事件会一直冒泡到 document 层次。
例子如下
123456789101112131415161718192021222324252627282930313233343536373839404142<body><ul id="myLinks"><li id="goSomewhere">Go somewhere</li><li id="doSomething">Do something</li><li id="sayHi">Say hi</li></ul><script type="text/javascript">(function(){var list = document.getElementById("myLinks");EventUtil.addHandler(list, "click", function(event){event = EventUtil.getEvent(event);var target = EventUtil.getTarget(event);switch(target.id){case "doSomething":document.title = "I changed the document's title";break;case "goSomewhere":location.href = "http://www.wrox.com";break;case "sayHi":alert("hi");break;}});})();</script></body>```- 总结:只取得了一个DOM元素,只添加了一个事件处理程序。占用的内存更少,所有用到按钮的事件都适合采用事件委托事件。### 移除事件处理程序- 每当事件处理程序指定给定的元素时,运行中的浏览器和支持页面交互的 js 代码就建立了一种连接。**这种连接越多,页面执行起来就越慢。**所以前面可以用事件委托限制建立连接的数量,另外,也应该注意在不需要的时候移除事件处理程序。 **内存中留有那些过时不用的 “空事件处理程序” ,也是造成 web 应用程序内存与性能问题的主要原因。**- 有两种情况造成“空事件处理程序”- removechild- xxx.innerHTML = "xxx";- 解决方法是手动移除事件处理程序:btn.onclick = function(){
btn.onclick = null;
xxx.innerHTML = “xxx”;
```
- 另一种情况是卸载页面时,有些浏览器会没有清理干净事件处理程序,造成对象滞留在内存中。
- 一般推荐的做法是在页面卸载之前,先通过 onload事件处理程序移除所有的事件处理程序。这样前面事件委托的优势就来啦,需要跟踪的 事件处理程序少了,移除就容易。