JS 事件介绍
1、设置js对象属性为事件处理程序
事件处理程序属性的名字由“on”后面跟着事件名组成。这些属性名 都必须小写
事件处理程序的缺点:设计都是围绕着假设每个事件目标对于每种事件类型将最多只有一个处理程序。
2、设置html标签属性为事件处理程序
属性值为javascript代码字符串。这段代码应该是事件处理程序函数的主体,而非完整的声明。
缺点:
客户端编程的通用风格是保持html内容和javascript行为分离,遵循这条规则的程序员禁止/避免使用html事件处理程序属性,因为这些属性直接混合了javascript和html
通过html属性注册事件处理函数时,浏览器会把javascript编码转换到一个函数中。非ie浏览器使用event参数来构造函数,而ie在构造函数时没有要求参数。
3.1、addEventListener
特点:能多次调用addEventListener为同一个对象注册同一事件类型的多个处理函数。
当对象发生事件时,所有该事件类型的注册处理程序都会按照注册的顺序调用。
3.2、attachEvent
ie9之前的版本支持
ie不支持事件捕获,所以attachEvent和detachEvent只有2个参数:事件类型和处理函数
ie下第一个参数使用了带“on”前缀的事件处理程序属性名,而非没有前缀的事件类型。
attachEvent允许相同的事件处理程序函数注册多次,当特定的事件类型发送时,注册函数的调用次数和注册次数一样。
4、事件处理程序的运行环境
在事件处理程序内,this关键字指的是事件目标。
甚至当使用addEventListener注册时,调用处理程序使用事件目标作为它们的this值。但是,对于attachEvent来讲这是不对的:使用attachEvent注册的处理程序作为函数调用,他们的this值是全局(window)对象。
解决:
function addEvent(target, type, handler) { if (target.addEventListener) { target.addEventListener(type, handler); } else { target.attachEvent("on" + type, function (event) { return handler.call(target, event); }) } }
//使用此方法时处理程序不能删除。
5、事件处理程序的作用域
事件处理函数从词法上讲也是作用域。它们在其定义时的作用域而非调用时的作用域中执行,并且能读取那个作用域中的任何一个本地变量。
html属性注册事件处理函数程序被转换为能存取全局变量的顶级函数而非任何本地变量。但是因为历史原因,它们运行在一个修改后的作用域链中。通过html属性定义的事件处理函数能好像本地变量一样使用目标对象、容器对象、Document对象的属性。
html属性最不自然的地方包括冗长的代码串和修改后的作用域链允许有用的快捷方式。
另一方面html事件处理程序中修改的作用域链是陷阱之源,因为作用域链中每个对象的属性在全局对象中都有相同名字的属性。
<button onclick="open()">按钮</button> <!--点击button后alert没有弹出--> <script type="text/javascript"> function open() { alert(1) } window.open(); <button id="ck" >按钮</button> <script type="text/javascript"> function open() { alert(1) } document.getElementById('ck').onclick = open;//alert出来1
6、事件处理程序的返回值
事件处理程序的返回值只对通过属性注册的出来程序才有意义。
7、调用顺序
通过设置对象属性或html属性注册的处理程序一直优先调用
使用addEventListener注册的处理程序按照他们的优先顺序调用
使用attachEvent注册的处理程序可能按照任何顺序调用,所以代码不应该依赖于调用顺序
8、事件传播
事件冒泡为在大量单独文档元素上注册处理程序提供了替代方案,即在共同的祖先元素上注册一个处理程序来处理所有的事件。
发生在文档元素上的大部分事件都会冒泡,值得注意的例外是focus、blur、scroll事件。
文档元素上的load事件,只会冒泡到 document对象上,不会传播到window对象。