JavaScript: 事件Event
事件触发JavaScript代码的过程分为3个步骤:
- 选中需要使用脚本的进行事件响应的元素节点
- 声明需要在选中节点上响应触发的事件(即事件绑定)
- 制定当事件发生时需要运行的代码
将事件绑定到元素的3种方法:
- HTML事件处理程序(不推荐) eg. <a onclick="hide()" />
- 传统的DOM事件处理程序 (只能在一个事件上附加一个函数)
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function() { 3 alert(this.id); //"myBtn" 4 }
- 第2级DOM监听器
element.addEventListener('event', functionName[, Boolean]);
-
- element 元素, 目标DOM元素节点
- event 事件, 需要绑定到节点的事件
- functionName 代码, 需要调用的函数名称
- Boolean 事件流, 制定是否为捕获方式的事件响应, 通常为false
1 function checkUsername(){ 2 //todo 3 } 4 5 var el = document.getElementById('username'); 6 el.addEventListener('el', checkUsername, false);
*使用函数checkUsername时去掉了小括号, 因为小括号表示函数会在页面加载到这里时运行, 而不是事件发生时运行
-
- 当选择的DOM节点上发生事件时, 如果调用一个命名函数的话, 需要首先编写这个函数
- 将DOM元素节点保存在一个变量中
- 和传统的HTML及DOM事件处理程序不同, 当指定需要坚挺的事件名称时, 不需要加'on'前缀
在事件处理程序和事件监听器种使用参数
由于在注册事件处理程序和事件监听器时, 在函数名后面是没有小括号的, 因此需要采用其他手段来传递参数
如果需要向事件处理程序或事件监听器所调用的函数传递参数, 就需要把方法封装在"匿名函数"中
eg.
1 el.addEventListener('blur', function(){ 2 checkUsername(5); 3 }, false)
事件流
- 事件冒泡
事件从最具体的节点开始向外传播到最宽泛的节点
<a> → <li> → <body> → <html> → <document>
- 事件捕获
事件从最宽泛的节点开始向内传播到最具体的节点
<document> → <html> → <body> → <li> → <a>
只有当代码在一个元素和其祖先元素或后代元素上都有事件处理程序时, 事件流才会变得非常重要.
事件对象
事件对象会作为参数传递给任何事件处理程序或事件监听器的函数.
如果需要传递一个参数给命名函数, 事件对象会作为匿名封装函数的第一个参数传递进去(自然发生), 然后需要为命名函数制定相应的参数
当事件对象被传递给函数时, 它的参数名称通常都是e(即event).
属性 | IE5~IE8中等价于 | 目标 |
target | srcElement | 事件的目标(与用户进行交互的最具体的元素) |
type | type | 发生的事件的类型 |
cancelable | 不支持 | 是否可以撤销事件在这个元素上的默认行为 |
方法 | IE5~IE8中等价于 | 目标 |
preventDefault() | returnValue | 撤销这个事件的默认行为(如果可以撤销的话) |
stopPropagation() | cancelBubble | 停止事件继续冒泡或向下捕获的过程 |
-
无参数的事件监听器
-
带参数的事件监听器
-
IE5~IE8中的事件对象
详细参考这里
事件委托
为大量的元素创建事件监听器会造成页面速度下降. 不过事件流允许在父元素上监听事件
事件可以影响到容器元素(或祖先元素), 因此可以将事件处理程序防止在一个容器元素上, 然后使用事件对象的target属性找到它的后代中是哪一个发生了事件.
当没有参数传递给函数时(不是从匿名函数中调用的), 可以使用this.
如果需要向函数传递参数, 那么this会失效. 因为这个函数的所有者不再是事件监听器所绑定的元素, 而是那个匿名函数. 需要把发生了事件的元素作为另一个参数传递给函数.