事件就是用户或者浏览器自身执行的某种动作诸如 clickload 和 mouseover, 都是事件的名字而响应某个事件的函数就叫事件处理程序事件处理程序的名字以 on 开头, 比如 click 事件的事件处理程序是 onclick 为事件指定事件处理程序的方式有多种方式
html 事件处理程序
元素支持的事件, 都可以使用与相应事件处理程序同名的 HTML 特性来指定这个特性的值能支持一定的 JavaScript 代码例如, 在单击按钮的时候执行一些 JavaScript 代码 <div id="aa" onclick="console.log('div')" style="width: 100px;">2222</div> , 当单击这个 div 的时候, 会在浏览器的控制台中输出 div 这个特性是通过 JavaScript 来实现的, 不能在其中使用未经转义的 HTML 语法字符, 例如和号 (&) 双引号 ("") 单引号 ('') 小于号 (<) 或者大于号(>)
在 HTML 中定义的事件处理程序可以包含要执行的具体动作, 也可以调用定义在其他页面的脚本
- function divClick(e) {
- var target = e.target;
- console.log("div");
- //stopBubble(e);
- }
- <div id="aa" onclick="divClick(event);" style="width: 100px;">2222</div>
上面的代码中, 点击 div 之后就会调用 divClick 函数这个函数是单独定义的 script 脚本中的, 当然也可以定义在一个外部文件中事件处理程序中的代码, 可以访问全局的方法上面的代码中, 同样可以传递 event 参数以及 this 参数 event 参数能够获取事件的类型参数等, 通过 this 能够获取点击对象本身
- function divClick(e) {
- //var target=e.target;
- console.log($(e).text()); //222
- //stopBubble(e);
- }
- <div id="aa" onclick="divClick(this);" style="width: 100px;">2222</div>
在 HTML 中指定事件处理程序有一定的缺点: 存在一定的时差, 用户可能在页面一出现就触发相应的事件, 但是事件处理程序尚不具备执行的条件上面的例子上, 如果 divClick 函数定义在 div 的下方, 我们在函数尚未解析之前, 就点击 div, 这样就会导致报错
另一个缺点是, 这样的事件处理程序的作用域链在不同的浏览器中会导致不同结果不同 JavaScript 引擎遵循的标识符解析规则略有差异, 很可能在访问非限定对象时出错
通过 HTML 指定事件处理程序的最后一个缺点是 HTML 与 JavaScript 代码的紧密耦合如果要更换事件处理程序就需要改动两个地方: JavaScript 和 HTML
DOM 级事件处理程序
通过 JavaScript 指定事件处理程序的传统方式是将一个函数赋值给事件处理程序属性通过 JavaScript 指定事件处理程序有两个优势: 简单和浏览器兼容性好要使用 JavaScript 指定事件处理程序, 首先必须获取一个元素的对象引用每个元素都有自己的事件处理程序, 这个属性通常是全部小写, 比如 onclick
- <div id="aa" style="width: 100px;">2222</div>
- <script>
- var a=document.getElementById("aa");
- a.onclick=function(e){
- var target=e.target;
- var text=target.innerHTML;
- console.log(text);//222
- }
- </script>
上面的代码, 通过文档对象获取了对象的引用, 然后为它指定了 onclick 事件处理程序 e 为点击事件的参数, 通过该参数能够获取点击事件的对象, 即 target 通过对象可以进一步获取对象的属性
- <div id="aa" style="width: 100px;">2222</div>
- <script>
- $("#aa").click(function(e){
- var target=e.target;
- var text=target.innerHTML;
- console.log(text);//222
- });
- </script>
这段代码与上面的例子实现的是一样的效果, 但是这个是通过 JQuery 来实现的
DOM2 级事件处理程序定义了两个方法, 用于处理指定和删除事件处理程序的操作: addEventListener 和 removeEventListener 所有 DOM 节点都包含这两个方法, 并且他们接收 3 个参数: 要处理的事件名作为事件处理程序的函数和一个布尔值布尔值如果为 true, 表示在捕获阶段执行事件处理程序, 如果为 false, 表示在冒泡阶段调用事件处理程序
- <div id="aa" style="width: 100px;">2222</div>
- <script>
- var a=document.getElementById("aa");
- a.addEventListener("click",function(e){
- console.log(this.id);
- },false);
- </script>
上面的例子通过 addEventListener 为元素 aa 添加了一个 click 事件通过事件处理程序能够访问到元素, this 和元素处在同一个作用域链
通过 DOM2 级可以通过添加多个事件处理程序事件处理程序会按照添加的顺序依次触发
- var a=document.getElementById("aa");
- a.addEventListener("click",function(e){
- console.log(this.id);
- },false);
- a.addEventListener("click",function(e){
- console.log(this.innerHTML);
- },false);
通过 addEventListener 添加的事件处理程序, 可以通过 removeEventListener 来移除事件处理程序但是, 有时候我们会走入一个误区
- var a=document.getElementById("aa");
- a.addEventListener("click",function(e){
- console.log(this.id);
- },false);
- a.removeEventListener("click",function(e){
- console.log(this.id);
- },false);
上面的代码我们使用 removeEventListener 方法移除事件处理程序, 但是并没有起作用在使用 addEventListener 和 removeEventListener 的时候, 第二个事件处理程序函数必须是同一个函数才会有作用, 我们对上面的代码作一个修改, 就可以了
- var a = document.getElementById("aa");
- var callback = function(e) {
- console.log(this.id);
- }
- a.addEventListener("click", callback, false);
- a.removeEventListener("click", callback, false);
上面的代码中, 我们在 addEventListener 和 removeEventListener 中调用的是同一个方法, 所以元素 aa 已经没有点击事件
对于 IE8 以及 IE8 以下浏览器来说, 它们并没有上述的两个方法, 但是提供了 attachEvent 和 detachEvent 两个方法这两个只需要传递两个参数: 第一参数事件程序名称, 第二个事件处理程序函数
- var a = document.getElementById("aa");
- var callback = function(e) {
- console.log(e.target.innerHTML);
- }
- //a.addEventListener("click",callback,false);
- //a.removeEventListener("click",callback,false);
- a.attachEvent("onclick", callback);
上面的代码通过 attachEvent 添加了事件处理程序, 但是 attachEvent 与 addEventListener 不一样在 attachEvent 的事件处理程序函数中 this 是指向 window 的, 我们无法获取元素对象
- var a=document.getElementById("aa");
- var callback=function(e){
- console.log(this.id);
- }
- //a.addEventListener("click",callback,false);
- //a.removeEventListener("click",callback,false);
- a.attachEvent("onclick",function(e){
- callback.call(a,e);
- });
上面的代码, 我们通过 call 修改了 this 的指向, 但是这样会带来另外一个问题, 怎么 detachEvent?
跨浏览器事件处理程序
为了以跨浏览器的事件处理程序, 开发人员可以封装适合自己的 js 库
- var EventUtil={
- addEvent:function(element,type,fn){
- if(element.addEventListener){
- element.addEventListener(type,fn,false);
- }
- else if(element.attachEvent){
- element.attachEvent("on"+type,fn);
- }
- else{
- element["on"+type]=fn;
- }
- },
- removeEvent:function(element,type,fn){
- if(element.removeEventListener){
- element.removeEventListener(type,fn,false);
- }
- else if(element.detachEvent){
- element.detachEvent("on"+type,fn);
- }
- else{
- element["on"+type]=null;
- }
- }
- };
- var aa=document.getElementById("aa");
- var func=function(e){
- console.log(e.type);
- EventUtil.removeEvent(aa,"click",func);
- }
- EventUtil.addEvent(aa,"click",func);
上面的 EventUtil 封装了一个跨浏览器的对象, 包含两个方法 addEvent 和 removeEvent 在第 25 行获取元素对象引用, 26 行定义了 fn 函数, 30 行调用 addEvent 添加了事件处理程序这个事件处理程序只能执行一次, 因为我们在 func 函数中又调用了 removeEvent 函数
来源: https://www.cnblogs.com/ggz19/p/8440516.html