js event事件对象概括

澳门新葡亰手机版 3

事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,比如单击、双击、鼠标悬浮等。

  事件是用户或者浏览器自身执行的动作,而响应某个事件的函数就叫做事件处理程序或者叫事件侦听器。

事件流

事件流描述的是从页面中接收事件的顺序,或者说是事件在页面中传播的顺序。

  • IE的事件流叫做事件冒泡(event
    bubbling)
    :由最具体的元素开始执行事件,然后逐级向上传播到 window
    对象。
  • 网景团队提出的事件流叫做事件捕获(event capturing):由最外层的
    window 对象开始执行事件,然后逐渐向下传播到最具体的元素。

下面我们做个小实验来说明这两种事件流的不同之处:

// html 文档
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件流 实验</title>
</head>
<body>
  <div id="test" style="font-size:3em;">点我点我,我是div</div>
</body>
</html>

// 事件冒泡
var div = document.getElementById("test");
div.addEventListener("click",function(){
  console.log("i am div");
}, false);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, false);
document.addEventListener("click",function(){
  console.log("i am document");
}, false);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);

澳门新葡亰手机版 1

点击div,控制端会打印如下:
i am div
i am body
i am html
i am document
i am window

// 事件捕获
var div = document.getElementById("test");
div.addEventListener("click",function(){
  console.log("i am div");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, true);
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, true);

澳门新葡亰手机版 2

图片经过二次处理,略丑,请见谅!

点击div,控制端会打印如下:
i am window
i am document
i am html
i am body
i am div

可以看出,事件冒泡和事件捕获是两种完全相反的事件流

平时,一般都是在使用事件冒泡,只在特殊情况下使用事件捕获。

DOM2级事件规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

// 事件冒泡和事件捕获混合一下
var div = document.getElementById("test");
div.addEventListener("click",function(){
  console.log("i am div");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);    // 改为在冒泡阶段调用事件处理程序
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);    // 改为在冒泡阶段调用事件处理程序

这个图片是直接从书上摘得,自己脑补一下,把 window 对象自行添上去吧!

澳门新葡亰手机版 3

点击div,控制端会打印如下:
i am document
i am html
i am div
i am body
i am window

定义事件处理程序可以大致分为以下三种:

事件处理程序

事件处理程序:指的是响应处理某个事件的函数

HTML 事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的 HTML
特性来指定。

// 情况一
<button onclick="alert('I am button!');">按钮</button>
// 情况二
<button onclick="show();">按钮</button>
<script>
function show(){
  alert("I am button!");
}
</script>

建议永远不要使用这种方式为元素添加事件,因为这种方法有一个巨大的缺点,就是使得
HTML 与 JavaScript 的代码紧密耦合,不符合网页设计的行为与结构分离。

DOM0 级事件处理程序

每个元素(包括 window 和 document)都有自己的事件处理程序属性,比如
onclick、onmouseup 等。

把上面的代码改写如下:

<button id="test">按钮</button>
var button = document.getElementById("test");
button.onclick = function(){
  // this 对象指向 button 元素
  console.log(this);
  alert("I am button!");
};
/*  删除指定的事件处理程序  */
button.onclick = null;

DOM2 级事件处理程序

DOM2
级事件
 定义了两个方法,用来处理指定和删除事件处理程序的操作:addEventListener()和 removeEventListener()

这两个方法都有三个参数,第一个参数是事件名,第二个参数是作为事件处理程序的函数,第三个参数是一个布尔值,默认值是
false,表示在冒泡阶段调用事件处理程序,如果这个值是
true,表示在捕获阶段调用事件处理程序。

继续改写上面的代码:

var button = document.getElementById("test");
function show(){
  // this 对象指向 button 元素
  console.log(this);
  alert("I am button!");
}
// 添加事件处理程序
button.addEventListener("click",show, false);
button.addEventListener("click",function(){
  alert("I am second alert!");
},false);
// 删除事件处理程序
button.removeEventListener("click",show, false); // 删除成功
button.removeEventListener("click",function(){   // 删除失败
  alert("I am second alert!");
},false);

使用 DOM2
级方法添加事件处理程序的主要好处是可以为一个元素添加多个事件处理程序。

如果 addEventListener() 添加的事件处理函数是匿名函数,则无法通过
removeEventListener() 删除这个事件处理程序。

IE 事件处理程序

IE8 以及更早的 IE 版本,只支持事件冒泡,不支持 addEventListener() 和
removeEventListener(),但是它实现了与这两个方法类似的两个方法:attachEvent() 和 detachEvent()。这两个方法只有两个参数,一个事件名称(是
onclick,不是 click),一个事件处理函数。

与 addEventListener() 不同,使用attachEvent()
方法的情况下,事件处理函数会在全局作用域下运行,所以 this 等于
window,这一点需要特别注意。

var button = document.getElementById("test");
button.attachEvent("onclick", function(){
  // this 对象指向了全局作用域,即 window
  console.log(this);
  alert("I am button!");
});
button.attachEvent("onclick",function(){
  alert("I am second alert!");
}); 
// 上面也是为同一个按钮绑定了两个事件处理程序
button.detachEvent("onclick",function(){ // 删除失败
  alert("I am second alert!");
});

除非你想使你的程序兼容至 IE8- 浏览器,否则不要使用这两个函数。

一、html事件处理程序

  元素支持的每种事件都可以用一个与之对应的事件处理程序的同名html特性来指定。

 <input type="button"  id="demo" onclick="alert(this.id)">

  这种方式创建的事件处理程序,里面有包含一个局部变量event,就是事件对象,在这个函数内部this等于事件的目标元素。且这个函数扩展了其作用域,可以像访问局部变量一样访问document和该元素的本身的属性成员。

   在html中指定事件处理程序的方式让html和js代码紧密耦合,不易维护。不推荐使用。

浏览器默认行为

对于一些特定的事件,浏览器有它默认的行为。比如:点击链接会进行跳转到指定的页面、点击鼠标右键会呼出浏览器右键菜单、填写表单时按回车会自动提交到服务器等。

默认的浏览器行为和冒泡行为是独立的,取消事件默认行为是不会取消事件冒泡的,反之亦然。同一个元素的多个事件处理函数也是相互独立的。

<div>
  <a id="test" href="http://baidu.com">点我点我,我是链接</a>
</div>
var link = document.getElementById("test");
// 方法一   event.preventDefault()
link.onclick = function(event){
  console.log("You click!");
  event.preventDefault();
};
// 方法二   return false
link.onclick = function(event){
  console.log("You click!");
  return false;
};

参考:事件-4.
浏览器默认行为-宇卿

二、dom元素方法

  通过js指定事件处理方式由来已久。方式就是将一个函数赋值给一个事件处理程序属性。

<div id="demo" class="hh">Web</div>
<script> 
  var demo=document.getElementById("demo");
    demo.onclick=function(){alert(this.className);} // alert(this.childNodes[0].nodeValue);输出web
</script>

  我们看到在上面的函数中可以通过this访问元素的任何属性和方法。

  将事件处理程序属性的值设为null可以删除它。

 demo.onclick=null;

事件对象 event

在触发 DOM 上的某个事件时,会产生一个事件对象
event,这个对象中包含着所有与该事件有关的信息。

event 对象只存在于事件处理程序执行期间,一旦执行完毕,立即被销毁。

<div>
  <a id="test" href="http://baidu.com">点我点我,我是链接</a>
</div>
/* 下列 event 对象的属性和方法都是只读的  */
var link = document.getElementById("test");
link.onclick = function(event){
  // 判断当前事件是否会向 DOM 树上层元素冒泡
  console.log(event.bubbles);

  // 判断是否可以取消事件的默认行为
  console.log(event.cancelable);
  // 使用该方法可以取消事件的默认行为(使用前提是 cancelable 属性的值为 true)
  event.preventDefault();
  // 判断是否已经调用了 preventDefault() 方法(DOM3级事件新增)
  console.log(event.defaultPrevented);

  // 指向事件遍历 DOM 时,识别事件的当前目标对象
  console.log(event.currentTarget);
  // 指向触发事件的对象
  console.log(event.target);

  // 表示事件流当前处于哪一个阶段
  // 值为 1 表示在捕获阶段,值为 2 表示处于目标阶段,值为 3 表示在冒泡阶段
  console.log(event.eventPhase);

  // 返回一个字符串, 表示该事件对象的事件类型
  console.log(event.type);

  // 立即停止当前事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡
  event.stopPropagation();
};

为了进一步说明 event.stopPropagation()
的运行效果,借用前面的代码,更改如下:

// 事件冒泡和事件捕获混合一下
var div = document.getElementById("test");
div.addEventListener("click",function(){
  console.log("i am div");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);    // 改为在冒泡阶段调用事件处理程序
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
  event.stopPropagation();    // 立即停止事件在 DOM 中的传播
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);    // 改为在冒泡阶段调用事件处理程序

点击div,控制端会打印如下:
i am document
i am html

看到了吧,后面元素的事件就不会被激发了。

三、addEventListener() / removeEventListener()方法

  所有DOM都包含这二个方法,ie6-8
不支持这个方法。这个方法接受三个参数:要处理的事件名称,事件处理程序和一个表示事件捕获或者冒泡的布尔值。

<div id="demo" class="ppp">Web</div>
<script>
 var demo=document.getElementById("demo");
   demo.addEventListener("click",function(){alert(this.childNodes[0].nodeValue);},false);//false表示冒泡阶段调用函数
 </script>

  该方法好处是可以为元素添加多个事件处理程序:

<div id="demo" class="ppp">Web</div>
<script>
 var demo=document.getElementById("demo");
   demo.addEventListener("click",function(){alert(this.childNodes[0].nodeValue);},false);
   demo.addEventListener("click",function(){alert(this.className);},false);
 </script>

  为div元素添加二个事件处理程序,点击后会按照添加的顺序依次弹出二条警示框。

  通过为removeEventListener()方法提供与添加处理程序相同的参数可以删除事件处理程序。

  function a(){alert(this.childNodes[0].nodeValue);};
  demo.addEventListener("click",a,false);
  demo.removeEventListener("click",a,false);

 

  ie有它自己的事件处理程序方法:attachEvent()和detachEvent()。这个方法只接受二个参数,因为ie8之前只支持事件冒泡,所以没有像addEventListener()方法中的第三个参数。这二个参数分别是:事件处理程序名称和事件处理程序函数。

<div id="demo" class="ppp">Web</div>
<script>
 var demo=document.getElementById("demo");
   function a(){alert("hi");};
   demo.attachEvent("onclick",a);//第一个参数是"onclick" 不是"click"
 </script>

澳门新葡亰手机版,   ie以attachEvent()方法运行的方式与上面addEventListener()方法运行的主要区别是事件的处理程序的作用域不同。

  在addEventListener()方法中程序是在所属的元素作用域中运行的;而ie的attachEvent()方法中程序是在全局作用域里运行的,它的this等于window。

事件类型

事件对象

  在触发DOM上的某个事件时会产生一个事件对象event,这个对象包含所有与事件有关的信息。包括鼠标点击的位置,键盘按下的键码、类型等等。