Javascript学习二:事件
【1】http://www.cnblogs.com/hh54188/archive/2012/02/08/2343357.html
【2】http://www.cnblogs.com/hh54188/archive/2012/02/17/2355658.html
1. 冒泡和捕获
2. 绑定机制
(1)行内事件绑定模型 inline event registration model
行内事件绑定模型的缺陷: javascript脚本与HTML标签混在一起,而且如果页面上有不止一个超链接需要同样的处理函数,需要写很多遍,在重复的同时也给维护带来了困难。
http://www.digital-web.com/articles/separating_behavior_and_structure_2/
<button name="demo" onClick="alert('I have been clicked!')"> click me</button>
或者
<button name="demo" onClick="doSomething()"> click me</button>
默认行为 default action
有默认行为的元素有:超链接,onload, unload(?浏览器事件响应)
<a href="http://google.com" onClick="doSomething()">anchor</a>
当我们点击超链接时,他会首先触发doSomething(),然后转到google。
阻止默认行为
无法阻止的默认行为:unload
- 使用返回值false阻止默认行为,这种情况下他会触发doSomething(),但是不会跳转到google
<a href="http://google.com" onClick="doSomething(); return false;">redirect?</a>
- W3C: preventDefault()
【2】中提高更改window.status,使用Chrome/Firefox/IE10没有更改,网上有人说是出于安全性考虑。
(2)传统事件绑定模型(【2】中的说法)
优点: 跨浏览器绑定事件的唯一方式
局限性:只能绑定一个函数,确切的说添加和删除绑定的多个函数的时候比较复杂(【2】)
element.onclick = doSomething;
<html> <head> </head> <body> <a href="http://google.com" class="print">hello</a> <a href="http://google.com" class="print">hello</a> <a href="http://google.com" class="print">hello</a> <a href="http://google.com" id="print">welcome</a> <script> var hello = document.getElementsByClassName("print"); // 给多个元素绑定相同事件时,要使用循环,挨个绑定 for (var i = hello.length - 1; i >= 0; i--) { hello[i].onclick = printInConsole; // 当绑定一个简单的事件处理函数时,可以采用匿名函数 // hello[i].onclick = function(){ // this.style.background = '#aa55aa'; // return false; // }; }; document.getElementById("print").onclick = printInConsole; function printInConsole(){ this.style.background = '#aa55aa'; return false; } </script> </body> </html>
【2】中提到“事件名称”必须是小写;赋值的函数doSomething不带括号。
赋值的函数带括号
element.onclick = doSomething(); //将doSomething()函数执行的结果赋值给whatever, 在执行这条赋值语句的时候,doSomething()被执行
赋值的函数不带括号
element.onclick = doSomething; //将doSomething函数绑定在onclick上,当onclick事件发生时,doSomething()被执行
(3.1)W3C事件绑定
优点:可以绑定任意数量的处理函数
缺点:无法找出某个元素绑定的函数(DOM Level 3中有,但是还没有被浏览器支持)
使用addEventListener()绑定函数,三个参数分别为:
- 事件类型eventType,可以是click, mouseout, mouseover等
- 需要执行的函数doSomething
- 布尔值boolean,true 或 false,表示处理函数在事件捕获阶段还是冒泡阶段执行,false表示冒泡阶段执行,true表示捕获阶段执行
element.addEventListener(eventType, doSomething, boolean);
<html> <head> </head> <body> <a href="http://google.com" id="click1">click1</a> <script> var click = document.getElementById("click1"); // chrome 会执行默认行为访问google,Firefox会阻止默认行为,但是页面一直加载请求访问google的网站 // 为什么会这样? click.addEventListener('click', printClick, false); click.addEventListener('click', printInConsole, false); // click.removeEventListener('click', printClick, false); function printInConsole(){ this.style.background = '#aa55aa'; return false; } function printClick(){ setTimeout(function(){ console.log("click doSomething");}, 3000); return false; } </script> </body> </html>
疑问:addEventListener不会阻止默认行为?(学习完后回来)
(3.2)微软事件绑定 【2】
如果和W3C模型比较,微软模型有两个严重的缺陷:
- 事件总是冒泡的,没有捕获的可能性
- 处理函数总是被引用,而非复制。所以其中的this关键字总是指向window,一点用都没有。
使用attachEvent绑定函数:
element.attachEvent('click', doSomething);
移除绑定使用:
element.detachEvent('click', doSomething)