js事件
温故而知新,很多东西了解但不是很明确就很容易忘记,项目中就会不断的踩坑,所以今天宅在家里看看js的事件部分,争取早日爬出这个坑,进入下一个,好了回归正题。
一、 有关事件的几个概念
- 事件流:描述从页面中接收事件的顺序
- 事件处理程序:响应某个事件的函数就叫做事件处理程序,或者叫做事件侦听器
- 事件对象:在DOM上触发一个事件的时候会产生一个事件对象event,它包含所有与该事件有关的信息
- 事件类型:
- ui事件,例如load,unload,resize,scroll
- 焦点事件,例如focus,blur,focusin,focusout(备注:focus,blur不会冒泡,但是focusin,focusout支持)
- 鼠标、滚轮事件,例如click, dblclick, mousedown, mouseenter......
- 键盘事件,例如keydown,keypress
(textInput)
,keyup
textInput事件与keypress稍有不同,区别之一是任何可以获取焦点的元素都可以触发keypress,但只有可编辑区域才能够触发textInput;二是textInput只有在用户按下能够输入实际字符的按键才会触发。另外event对象上还会有一个inputMethod属性表示输入到文本框的方式,例如1表示键盘输入,2表示粘贴......
- 合成事件,例如compositionstart, compositionupdate,compositionend,这些事件会在输入框搜索建议的地方用到,后面会单独用一个文章说明
- 变动事件
- HTML5事件,例如hashchange
- 设备事件
- 触摸与手势事件,例如touchstart,touchmove,touchend
二、DOM事件流的三个阶段
- 事件捕获阶段
即事件从不太具体的节点开始最后是具体节点接收事件。ie9+支持
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button>click</button>
</body>
</html>
上面的代码会依次发生在window --> document --> html --> body --> button
- 处于目标阶段
- 事件冒泡阶段
即事件开始由最具体的元素接收然后逐级向上传播,所有现代浏览器都支持冒泡,但是具体会有差异。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button>click</button>
</body>
</html>
上面的代码会依次发生在button --> body --> html --> document
备注:ie5.5以及更早的版本会跳过document;ie9,firefox,chrome和safari都是将事件最后冒泡到window上面的
DOM2级事件
规定首先发生的是事件捕获,为捕获事件提供了机会,然后是实际的目标接收到事件,最后一个阶段是冒泡,对事件作出响应
三、利用DOM事件流做事件代理
一个表格,里面含有N跳数据,每一条点击的时候都会展示对应的详情,结构如下
<ul>
<li><span>xxxxxx</span><button>点击查看详情</button></li>
<li><span>xxxxxx</span><button>点击查看详情</button></li>
<li><span>xxxxxx</span><button>点击查看详情</button></li>
<li><span>xxxxxx</span><button>点击查看详情</button></li>
<li><span>xxxxxx</span><button>点击查看详情</button></li>
</ul>
很明显,如果给上面的每一个button绑定一个事件就会绑定很多事件,这个时候我们就可以利用事件的冒泡仅仅指定一个事件处理程序来处理这些事件,这个处理方式叫做事件代理
延伸问题
:既然事件的代理是依靠事件冒泡的原理,那么blur和focus事件不支持冒泡,怎么处理呢?
用focusin,focusout?yes,但是这两个事件是不兼容的,所以需要特殊处理
- focusin 与 focusout的浏览器支持
几乎所有的浏览器都支持focus和blur事件,但对于focusin和focusout 就不是这样理想了。Firefox中不支持focusin和focusout事件;chrome和safari中只有通过addEventListener方式绑定事件才能正常使用,其他方式绑定都不行 - 根据上面的支持,我们可以分为用addEventListener在捕获阶段绑定focus/blur的和直接绑定focusin,focusout的,示例代码如下
function consoleA (){
console.log('a')
}
var form = document.forms['form'];
if (form.addEventListener) { // 非 IE 浏览器
// 注意这个后面的参数是true,则表示是在捕获阶段的
form.addEventListener('focus', consoleA, true);
}else{ // IE
form.onfocusin = consoleA
}
之前也记录过一个关于blur和click事件踩过的坑,可以点击查看http://www.jianshu.com/p/7d48cbe0a640
好了,这个文章就记录到这里,欢迎指正