精品建站教程,广告优化师前景,什么是营销模式,北京网站手机站建设公司事件参考 
事件介绍 
触发事件是为了通知代码可能影响代码执行的“有趣变化”。这些可能来自用户交互#xff0c;例如使用鼠标或调整窗口大小#xff0c;底层环境状态的变化(例如#xff0c;低电量或来自操作系统的媒体事件)以及其他原因。 
每个事件都由一个基于Event接口的…事件参考 
事件介绍 
触发事件是为了通知代码可能影响代码执行的“有趣变化”。这些可能来自用户交互例如使用鼠标或调整窗口大小底层环境状态的变化(例如低电量或来自操作系统的媒体事件)以及其他原因。 
每个事件都由一个基于Event接口的对象表示并且可能有额外的自定义字段和/或函数来提供关于发生的事情的信息。每个事件的文档都有一个表(靠近顶部)其中包括到相关事件接口的链接以及其他相关信息。 Event  Interfaces based on Event中给出了不同事件类型的完整列表。 
本主题提供了您可能感兴趣的主要类型事件(动画剪贴板workers 等)的索引以及实现这些类型事件的主要类。最后是所有记录事件的扁平列表。 注意:本页列出了许多你在网上会遇到的最常见的事件。如果您正在搜索此处未列出的事件请尝试在MDN的其余部分搜索其名称、主题区域或相关规范。 Event index 
Event listing 本节列出了在MDN上有自己参考页面的事件。如果您对此处未列出的事件感兴趣请尝试在MDN的其余部分搜索其名称、主题领域或相关规范。 
1、创建和触发事件 
本文演示了如何创建和分派DOM事件。这些事件通常被称为合成事件synthetic events与浏览器本身触发的事件相反。 
1.1 创建自定义事件 
事件可以用Event构造函数创建如下所示: 
const event  new Event(build);// Listen for the event.
elem.addEventListener(build,(e)  {/* … */},false,
);// Dispatch the event.
elem.dispatchEvent(event);上面的代码示例使用了EventTarget.dispatchEvent()方法。 
大多数现代浏览器都支持此构造函数。要了解更详细的方法请参见下面的老式方法。 
添加自定义数据- CustomEvent() 
要向事件对象添加更多数据存在CustomEvent接口并且可以使用detail属性来传递自定义数据。例如可以这样创建事件: 
const event  new CustomEvent(build, { detail: elem.dataset.time });这将允许您访问事件监听器中的其他数据: 
function eventHandler(e) {console.log(The time is: ${e.detail});
}老式的方式 
创建事件的旧方法使用受Java启发的api。下面是一个使用document.createEvent()的示例: 
// Create the event.
const event  document.createEvent(Event);// Define that the event name is build.
event.initEvent(build, true, true);// Listen for the event.
elem.addEventListener(build,(e)  {// e.target matches elem},false,
);// target can be any Element or other EventTarget.
elem.dispatchEvent(event);事件冒泡 
通常希望从子元素触发事件并让一个祖先捕获它;可选的带数据: 
formtextarea/textarea
/formconst form  document.querySelector(form);
const textarea  document.querySelector(textarea);// Create a new event, allow bubbling, and provide any data you want to pass to the detail property
const eventAwesome  new CustomEvent(awesome, {bubbles: true,detail: { text: ()  textarea.value },
});// The form element listens for the custom awesome event and then consoles the output of the passed text() method
form.addEventListener(awesome, (e)  console.log(e.detail.text()));// As the user types, the textarea inside the form dispatches/triggers the event to fire, and uses itself as the starting point
textarea.addEventListener(input, (e)  e.target.dispatchEvent(eventAwesome));动态创建和调度事件 
元素可以监听尚未创建的事件: 
formtextarea/textarea
/formconst form  document.querySelector(form);
const textarea  document.querySelector(textarea);form.addEventListener(awesome, (e)  console.log(e.detail.text()));textarea.addEventListener(input, function () {// Create and dispatch/trigger an event on the fly// Note: Optionally, weve also leveraged the function expression (instead of the arrow function expression) so this will represent the elementthis.dispatchEvent(new CustomEvent(awesome, {bubbles: true,detail: { text: ()  textarea.value },}),);
});1.2 触发内置事件 
这个示例演示了使用DOM方法模拟复选框上的单击(以编程方式生成单击事件)。查看实际示例 
function simulateClick() {const event  new MouseEvent(click, {view: window,bubbles: true,cancelable: true,});const cb  document.getElementById(checkbox);const cancelled  !cb.dispatchEvent(event);if (cancelled) {// A handler called preventDefault.alert(cancelled);} else {// None of the handlers called preventDefault.alert(not cancelled);}
}2、事件处理(概述) 
事件是在浏览器窗口内触发的信号用于通知浏览器或操作系统环境中的更改。程序员可以创建在事件触发时运行的事件处理程序event handler代码从而允许网页对变化做出适当的响应。 
本页提供了一个关于如何使用事件和事件处理程序的非常简短的“提醒”。新开发者应该阅读事件简介。 
2.1 可用的事件有哪些? 
事件记录在发出事件的JavaScript对象的页面中或页面下方。例如要查找浏览器窗口或当前文档上触发的事件请参阅“窗口”和“文档”中的“事件”部分。 
你可以使用 Event 参考来查找哪些JavaScript对象为特定的 APIs 触发事件例如动画、媒体等等。 
2.2 注册事件处理程序 
有两种推荐的方法来注册处理程序。事件处理程序代码可以在触发事件时运行方法是将其分配给目标元素对应的onevent属性或者使用addEventListener()方法将处理程序注册为元素的监听器。在任何一种情况下处理程序都将接收一个符合Event接口(或派生接口)的对象。主要区别在于可以使用事件监听器方法添加(或删除)多个事件处理程序。 警告:不推荐使用HTML onevent属性设置事件处理程序的第三种方法!它们使标记膨胀使其可读性降低更难调试。有关更多信息请参阅内联事件处理程序。 2.2.1 使用 onevent 属性 
按照约定触发事件的JavaScript对象具有相应的“onevent”属性(通过在事件名称前加上前缀“on”来命名)。在触发事件时调用这些属性以运行相关的处理程序代码也可以由您自己的代码直接调用这些属性。 
要设置事件处理程序代码只需将其分配给适当的onevent属性。元素中的每个事件只能分配一个事件处理程序。如果需要可以通过将另一个函数分配给同一属性来替换处理程序。 
下面我们将展示如何使用onclick属性为click事件设置一个简单的greet()函数。 
const btn  document.querySelector(button);function greet(event) {console.log(greet:, event);
}btn.onclick  greet;**请注意将表示事件的对象作为第一个参数传递给事件处理程序。**此事件对象实现Event接口或从Event接口派生。 
2.2.2 EventTarget.addEventListener 
在元素上设置事件处理程序的最灵活的方法是使用EventTarget.addEventListener方法。这种方法允许将多个监听器分配给一个元素并在需要时删除侦听器(使用EventTarget.removeEventListener)。 注意:添加和删除事件处理程序的功能允许您例如让相同的按钮在不同的情况下执行不同的操作。此外在更复杂的程序中清理旧的/未使用的事件处理程序可以提高效率。 下面我们将展示如何将一个简单的greet()函数设置为click事件的监听器/事件处理程序(如果需要可以使用lambda函数而不是命名函数)。再次注意事件作为第一个参数传递给事件处理程序。 
const btn  document.querySelector(button);function greet(event) {console.log(greet:, event);
}btn.addEventListener(click, greet);该方法还可以使用其他参数/选项来控制捕获和删除事件的方式。更多信息可以在EventTarget.addEventListener引用页上找到。 
2.2.3 使用中止信号 
一个值得注意的事件监听器特性是能够使用中止信号同时清理多个事件处理程序。 
这是通过将相同的AbortSignal传递给您希望能够一起删除的所有事件处理程序的addEventListener()调用来完成的。然后您可以在拥有AbortSignal的控制器上调用abort()它将删除与该信号一起添加的所有事件处理程序。例如要添加一个可以用AbortSignal删除的事件处理程序: 
const controller  new AbortController();btn.addEventListener(click,(event)  {console.log(greet:, event);},{ signal: controller.signal },
); // pass an AbortSignal to this handler然后上面代码创建的事件处理程序可以像这样删除: 
controller.abort(); // removes any/all event handlers associated with this controller3、 js 构建块事件介绍 
事件是在您正在编程的系统中发生的事情系统会告诉您有关这些事件的信息以便您的代码能够对它们做出反应。 
例如如果用户单击网页上的一个按钮您可能希望通过显示一个信息框来对该操作作出反应。在本文中我们将讨论与事件相关的一些重要概念并研究它们在浏览器中的工作方式。这不会是一个详尽的研究;这就是你现在需要知道的。 
3.1 什么是事件? 
事件是在您正在编程的系统中发生的事情—当事件发生时系统产生(或“触发”produces (or “fires”))某种类型的信号并提供一种机制通过该机制可以在事件发生时自动采取操作(即运行某些代码)。事件在浏览器窗口内触发并且倾向于附加到驻留在其中的特定项。这可能是单个元素、一组元素、当前选项卡中加载的HTML文档或整个浏览器窗口。可能发生许多不同类型的事件。 
例如 
用户选择、单击或将光标悬停在某个元素上。用户在键盘上选择一个键。用户调整或关闭浏览器窗口。网页加载完成。提交表单。视频开始播放、暂停或结束。出现错误。 
您可以从这里(以及浏览MDN事件引用)了解到有很多事件可以被触发。 
要对事件作出反应需要将事件处理程序event handler附加到事件上。这是在事件触发时运行的代码块(通常是程序员创建的JavaScript函数)。当这样的代码块被定义为响应一个事件而运行时我们说我们正在注册一个事件处理程序( registering an event handler)。注意:事件处理程序有时被称为事件监听器(event listeners)——它们在我们的目的中几乎是可互换的尽管严格地说它们是一起工作的。监听器监听事件的发生处理程序是响应事件发生而运行的代码。 注意:Web事件不是JavaScript核心语言的一部分——它们被定义为浏览器内置APIs 的一部分。 示例:处理单击事件 
在下面的例子中我们在页面中只有一个button: 
buttonChange color/button然后我们有一些JavaScript。我们将在下一节中更详细地讨论这个问题但现在我们只能说:它为按钮的“click”事件添加了一个事件处理程序并且处理程序通过将页面背景设置为随机颜色来响应事件: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}btn.addEventListener(click, ()  {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
});示例输出如下。试着点击这个按钮:  
3.2 使用addEventListener () 
正如我们在上一个示例中看到的可以触发事件的对象有一个addEventListener()方法这是添加事件处理程序的推荐机制。 
让我们仔细看看最后一个例子中的代码: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}btn.addEventListener(click, ()  {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
});当用户单击按钮时HTML button元素将触发一个事件。所以它定义了一个addEventListener()函数我们在这里调用它。我们传入两个参数: 
字符串click表示我们想要监听click事件。按钮可以触发许多其他事件例如当用户将鼠标移动到按钮上时发生mouseover或者当用户按下一个键并且按钮定焦时发生“keydown”。当事件发生时调用的函数。在我们的示例中该函数生成一个随机的RGB颜色并将页面body的背景色background-color设置为该颜色。 
让handler函数成为一个单独的命名函数是可以的像这样: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}function changeBackground() {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
}btn.addEventListener(click, changeBackground);监听其他事件 
一个按钮元素可以触发许多不同的事件。继续我们的实验。 
首先在本地复制random-color-addeventlistener.html并在浏览器中打开它。这只是一个简单的随机颜色的例子的复制我们已经玩过了。现在尝试依次将click更改为以下不同的值并观察示例中的结果: 
focus and blur -当按钮聚焦和未聚焦时颜色会发生变化;尝试按TAB键聚焦在按钮上然后再按TAB键将焦点从按钮移开。这些通常用于在表单字段聚焦时显示有关填充表单字段的信息或者在表单字段填充了不正确的值时显示错误消息。dblclick 只有双击按钮时颜色才会改变。mouseover and mouseout 当鼠标指针悬停在按钮上或指针离开按钮时颜色分别发生变化。 
有些事件(如click)几乎可以在任何元素上使用。另一些则更具体只在某些情况下有用:例如play事件只对某些元素可用如video。 
删除监听器 
如果您使用addEventListener()添加了一个事件处理程序您可以使用removeEventListener()方法再次删除它。例如这将删除changeBackground()事件处理程序: 
btn.removeEventListener(click, changeBackground);事件处理程序也可以通过将AbortSignal传递给addEventListener()然后在拥有AbortSignal的控制器上调用abort()来删除。例如要添加一个可以用AbortSignal删除的事件处理程序: 
const controller  new AbortController();btn.addEventListener(click,()  {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;},{ signal: controller.signal } // pass an AbortSignal to this handler
);然后上面代码创建的事件处理程序可以像这样删除: 
controller.abort(); // removes any/all event handlers associated with this controller对于简单的小程序清理旧的、未使用的事件处理程序是没有必要的但是对于更大、更复杂的程序它可以提高效率。此外删除事件处理程序的功能允许您让相同的按钮在不同的情况下执行不同的操作:您所要做的就是添加或删除处理程序。 
为单个事件添加多个监听器 
通过对addEventListener()进行多个调用提供不同的处理程序您可以为单个事件提供多个处理程序: 
myElement.addEventListener(click, functionA);
myElement.addEventListener(click, functionB);现在当单击元素时这两个函数都将运行。 
Learn more 
addEventListener()还有其他强大的特性和选项可用。 
这些内容超出了本文的范围但是如果您想阅读它们请访问addEventListener()和removeEventListener()参考页面。 
3.3 其他事件监听器机制 
我们建议您使用addEventListener()来注册事件处理程序。它是最强大的方法适用于更复杂的程序。但是您可能还会看到另外两种注册事件处理程序的方式:事件处理程序属性(event handler properties)和内联事件处理程序(inline event handlers)。 
事件处理程序属性 
可以触发事件的对象(如按钮)通常也具有名称为on的属性后面跟着事件名称。例如元素有一个onclick属性。这称为事件处理程序属性。要监听事件可以将处理函数分配给属性。 
例如我们可以这样重写随机颜色的例子: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}btn.onclick  ()  {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
};你也可以将handler属性设置为一个命名函数: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}function bgChange() {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
}btn.onclick  bgChange;使用事件处理程序属性您不能为单个事件添加多个处理程序。例如你可以在一个元素上多次调用addEventListener(click, handler)并在第二个参数中指定不同的函数: 
element.addEventListener(click, function1);
element.addEventListener(click, function2);这对于事件处理程序属性是不可能的因为任何后续尝试设置该属性都会覆盖先前的属性: 
element.onclick  function1;
element.onclick  function2;内联事件处理程序——不要使用这些 
你可能也会在你的代码中看到这样的模式: 
button onclickbgChange()Press me/buttonfunction bgChange() {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});document.body.style.backgroundColor  rndCol;
}在Web上注册事件处理程序的最早方法涉及事件处理程序HTML属性(或内联事件处理程序)如上面所示—属性值实际上是您希望在事件发生时运行的JavaScript代码。上面的例子调用了在同一页面的script元素中定义的函数但是你也可以直接在属性中插入JavaScript例如: 
button onclickalert(Hello, this is my old-fashioned event handler!);Press me
/button你可以找到许多事件处理程序属性的对等HTML属性;然而你不应该使用这些——它们被认为是不好的做法。如果您正在快速执行某些操作那么使用事件处理程序属性似乎很容易但是它们很快就会变得难以管理且效率低下。 
首先将HTML和JavaScript混在一起并不是一个好主意因为这会变得难以阅读。保持JavaScript独立是一种很好的做法如果它位于单独的文件中则可以将其应用于多个HTML文档。 
即使在单个文件中内联事件处理程序也不是一个好主意。一个按钮是可以的但是如果你有100个按钮呢?你必须在文件中添加100个属性;它很快就会变成一场维修噩梦。使用JavaScript你可以很容易地为页面上的所有按钮添加事件处理函数无论有多少按钮使用如下代码: 
const buttons  document.querySelectorAll(button);for (const button of buttons) {button.addEventListener(click, bgChange);
}最后作为一种安全措施许多常见的服务器配置将不允许内联JavaScript。 
永远不要使用HTML事件处理程序属性——这些属性已经过时了使用它们是不好的做法。 
3.4 Event 对象 
有时在事件处理程序函数中您会看到一个指定了名称的参数如event、evt或e。这称为事件对象(event object)它被自动传递给事件处理程序以提供额外的功能和信息。例如让我们再重写一下随机颜色的例子: 
const btn  document.querySelector(button);function random(number) {return Math.floor(Math.random() * (number  1));
}function bgChange(e) {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});e.target.style.backgroundColor  rndCol;console.log(e);
}btn.addEventListener(click, bgChange);注意:你可以在GitHub上找到这个例子的完整源代码。 在这里你可以看到我们在函数中包含了一个事件对象e并在函数中为e.target(即按钮本身)设置了背景颜色样式。事件对象的target 属性始终是对发生事件的元素的引用。因此在这个例子中我们在按钮上设置一个随机的背景颜色而不是页面。 注意:请参阅下面的事件委托部分以获取我们使用event.target的示例。 注意:您可以为事件对象使用任何您喜欢的名称—您只需要选择一个您可以在事件处理程序函数中引用它的名称。e /evt/event最常被开发人员使用因为它们简短且易于记忆。保持一致总是好的——对自己如果可能的话对别人。 事件对象的额外属性 
大多数事件对象在事件对象上都有一组标准的属性和方法;有关完整列表请参阅Event对象参考。 
一些事件对象添加了与特定类型的事件相关的额外属性。例如当用户按下一个键时触发keydown事件。它的事件对象是一个KeyboardEvent它是一个特殊的事件对象带有一个key属性告诉你按下了哪个键: 
input idtextBox typetext /
div idoutput/divconst textBox  document.querySelector(#textBox);
const output  document.querySelector(#output);
textBox.addEventListener(keydown, (event)  {output.textContent  You pressed ${event.key}.;
});3.5 防止默认行为 
有时您会遇到这样一种情况:您希望阻止事件执行其默认执行的操作。最常见的例子是web表单例如自定义注册表单。当您填写详细信息并单击提交按钮时自然的行为是将数据提交到服务器上的指定页面进行处理并将浏览器重定向到某种“成功消息”页面(如果未指定另一个页面则为同一页面)。 
当用户没有正确提交数据时麻烦就来了——作为开发人员您希望阻止向服务器提交数据并给出一个错误消息说明哪里出错了需要做些什么来纠正错误。有些浏览器支持自动表单数据验证功能但由于许多浏览器不支持因此建议您不要依赖这些功能而是实现自己的验证检查。让我们看一个简单的例子。 
首先是一个简单的HTML表单它需要你输入你的姓和名: 
formdivlabel forfnameFirst name: /labelinput idfname typetext //divdivlabel forlnameLast name: /labelinput idlname typetext //divdivinput idsubmit typesubmit //div
/form
p/p现在是一些JavaScript——这里我们在submit事件的处理程序中实现了一个非常简单的检查(提交事件在表单提交时触发)测试文本字段是否为空。如果是我们调用事件对象上的preventDefault()函数——它会停止表单提交——然后在表单下面的段落中显示一个错误消息告诉用户哪里出错了: 
const form  document.querySelector(form);
const fname  document.getElementById(fname);
const lname  document.getElementById(lname);
const para  document.querySelector(p);form.addEventListener(submit, (e)  {if (fname.value   || lname.value  ) {e.preventDefault();para.textContent  You need to fill in both names!;}
});显然这是非常弱的表单验证—例如它不会阻止用户验证字段中输入空格或数字的表单—但对于示例目的来说它是可以的。输出结果如下:  注意:要获得完整的源代码请参阅preventdefault-validate .html。 3.6 事件冒泡 
事件冒泡Event bubbling描述了浏览器如何处理针对嵌套元素的事件。 
3.6.1 在父元素上设置监听器 
考虑这样一个网页: 
div idcontainerbuttonClick me!/button
/div
pre idoutput/pre这里按钮位于另一个元素div元素中。我们说这里的div元素是它所包含元素的父元素。如果我们向父类添加click事件处理程序然后单击按钮会发生什么情况? 
const output  document.querySelector(#output);
function handleClick(e) {output.textContent  You clicked on a ${e.currentTarget.tagName} element\n;
}const container  document.querySelector(#container);
container.addEventListener(click, handleClick);你会看到当用户单击按钮时父类会触发一个click事件: 
这是有道理的:按钮位于div内部因此当您单击按钮时您也隐式地单击了它所在的元素。 
3.6.2 冒泡的例子 
如果我们向按钮和父控件添加事件侦听器会发生什么? 
bodydiv idcontainerbuttonClick me!/button/divpre idoutput/pre
/body让我们尝试将click事件处理程序添加到按钮、它的父元素(div)和包含它们的body元素中: 
const output  document.querySelector(#output);
function handleClick(e) {output.textContent  You clicked on a ${e.currentTarget.tagName} element\n;
}const container  document.querySelector(#container);
const button  document.querySelector(button);document.body.addEventListener(click, handleClick);
container.addEventListener(click, handleClick);
button.addEventListener(click, handleClick);您将看到当用户单击按钮时这三个元素都会触发一个click事件: 
You clicked on a BUTTON element
You clicked on a DIV element
You clicked on a BODY element在这种情况下: 
首先触发按钮上的单击然后是其父元素(div元素)的单击然后是div元素的父元素(body元素)。 
我们将其描述为事件从被点击的最内层元素冒出来( bubbles up)。 
这种行为可能很有用但也可能导致意想不到的问题。在接下来的部分中我们将看到它引起的一个问题并找到解决方案。 
3.6.3 视频播放器示例 
在这个例子中我们的页面包含一个视频它最初是隐藏的还有一个标签为“显示视频”的按钮。我们需要以下交互: 
当用户点击“显示视频”按钮时显示包含视频的框但还没有开始播放视频。当用户点击视频时开始播放视频。当用户点击视频外框中的任何位置时隐藏该框。 
HTML看起来是这样的: 
buttonDisplay video/buttondiv classhiddenvideosourcesrchttps://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webmtypevideo/webm /pYour browser doesnt support HTML video. Here is aa hrefrabbit320.mp4link to the video/a instead./p/video
/div它包括: 
button元素一个最初具有classhidden属性的div元素嵌套在div元素中的video元素。 
我们使用CSS来隐藏带有hidden类集的元素。 
const btn  document.querySelector(button);
const box  document.querySelector(div);
const video  document.querySelector(video);btn.addEventListener(click, ()  box.classList.remove(hidden));
video.addEventListener(click, ()  video.play());
box.addEventListener(click, ()  box.classList.add(hidden));您应该看到当您单击该按钮时将显示该框及其包含的视频。但是当你点击视频时视频开始播放但是盒子又被隐藏了! 
视频位于div内部——它是div的一部分——因此单击视频会同时运行两个事件处理程序从而导致这种行为。 
3.6.4 使用stopPropagation()修复问题 
正如我们在上一节中看到的事件冒泡有时会产生问题但是有一种方法可以防止它。Event对象上有一个名为stopPropagation()的函数当在事件处理程序中调用该函数时可以防止事件冒泡到任何其他元素。 
我们可以通过修改JavaScript来解决当前的问题: 
const btn  document.querySelector(button);
const box  document.querySelector(div);
const video  document.querySelector(video);btn.addEventListener(click, ()  box.classList.remove(hidden));video.addEventListener(click, (event)  {event.stopPropagation();video.play();
});box.addEventListener(click, ()  box.classList.add(hidden)); 
我们在这里所做的只是在video元素的’click’事件的处理程序中对事件对象调用stopPropagation()。这将阻止事件冒泡到盒子中。现在试着点击按钮然后点击视频: 
3.6.5 事件捕获 
事件传播的另一种形式是事件捕获 event capture。这类似于事件冒泡但顺序相反:事件不是首先在最内层的目标元素上触发然后依次在嵌套较少的元素上触发事件首先在嵌套最少(least nested)的元素上触发然后依次在嵌套较多的元素上触发直到到达目标。 
默认情况下事件捕获是禁用的。要启用它必须在addEventListener()中传递capture 选项。 
这个例子就像我们之前看到的冒泡的例子除了我们使用了capture 选项: 
bodydiv idcontainerbuttonClick me!/button/divpre idoutput/pre
/bodyconst output  document.querySelector(#output);
function handleClick(e) {output.textContent  You clicked on a ${e.currentTarget.tagName} element\n;
}const container  document.querySelector(#container);
const button  document.querySelector(button);document.body.addEventListener(click, handleClick, { capture: true });
container.addEventListener(click, handleClick, { capture: true });
button.addEventListener(click, handleClick);在这种情况下消息的顺序是颠倒的:body事件处理程序首先触发然后是div事件处理程序然后是button事件处理程序: 
为什么要同时捕获和冒泡呢?在糟糕的过去浏览器的交叉兼容性远不如现在Netscape只使用事件捕获Internet Explorer只使用事件冒泡。当W3C决定尝试标准化行为并达成共识时他们最终采用了包含这两者的系统这就是现代浏览器实现的。 
默认情况下几乎所有事件处理程序都注册在冒泡阶段这在大多数情况下更有意义。 
3.7 事件委托 
在上一节中我们研究了由事件冒泡引起的问题以及如何修复它。不过事件冒泡并不只是令人讨厌它可以非常有用。特别是它支持事件委托event delegation。在这个实践中当我们希望某些代码在用户与大量子元素中的任何一个交互时运行时我们在它们的父元素上设置事件监听器并让发生在它们身上的事件冒泡到它们的父元素上而不必在每个子元素上单独设置事件侦听器。 
让我们回到我们的第一个例子,当用户点击一个按钮时,我们设置整个页面的背景颜色。假设,页面被划分为16块区域,当用户点击那个区域时,我们想要设置每个瓷砖的随机颜色。 
div idcontainerdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/divdiv classtile/div
/div我们有一个小小的CSS用来设置贴图的大小和位置: 
.tile {height: 100px;width: 25%;float: left;
}现在在JavaScript中我们可以为每个tile添加一个click事件处理程序。但一个更简单、更有效的选择是在父类上设置click事件处理程序并依靠事件冒泡来确保当用户单击tile时处理程序被执行: 
function random(number) {return Math.floor(Math.random() * number);
}function bgChange() {const rndCol  rgb(${random(255)}, ${random(255)}, ${random(255)});return rndCol;
}const container  document.querySelector(#container);container.addEventListener(click, (event)  {event.target.style.backgroundColor  bgChange();
});注意:在本例中我们使用event.target获取作为事件目标的元素(即最内层元素)。如果我们想要访问处理该事件的元素(在本例中是容器)我们可以使用event.currentTarget。 注意:完整的源代码见useful-eventtarget.html;也可以在这里看到它的现场运行。 不仅仅是网页 
事件并不是JavaScript独有的——大多数编程语言都有某种事件模型而模型的工作方式通常与JavaScript的方式不同。事实上用于网页的JavaScript事件模型不同于用于其他环境的JavaScript事件模型。 
例如Node.js是一个非常流行的JavaScript运行时它使开发人员能够使用JavaScript构建网络和服务器端应用程序。Node.js事件模型依赖于监听器来监听事件依赖于发射器来周期性地发出事件——听起来没有什么不同但代码却大不相同使用on()等函数来注册事件监听器使用once()来注册事件监听器该事件监听器在运行一次后取消注册。HTTP连接事件文档提供了一个很好的例子。 
你也可以使用JavaScript构建跨浏览器的插件——使用一种叫做WebExtensions的技术来增强浏览器的功能。事件模型类似于web事件模型但有一点不同——事件侦听器的属性是以驼峰形式编写的(例如onMessage而不是onmessage)并且需要与addListener函数结合使用。查看runtime.onMessage页面例子。 
在学习的这个阶段你不需要了解其他类似的环境;我们只是想说明事件在不同的编程环境中是不同的。 
See also 
Event referenceEvent order (关于捕获和冒泡的讨论)——Peter-Paul Koch写的一篇非常详细的文章。事件访问 (关于事件对象的讨论)——彼得-保罗·科赫的另一篇非常详细的文章domevents.dev 一个非常有用的交互式游乐场应用程序可以通过探索来学习DOM事件系统的行为。 文章转载自: http://www.morning.pjwml.cn.gov.cn.pjwml.cn http://www.morning.bgpch.cn.gov.cn.bgpch.cn http://www.morning.wnhsw.cn.gov.cn.wnhsw.cn http://www.morning.ypbdr.cn.gov.cn.ypbdr.cn http://www.morning.plxhq.cn.gov.cn.plxhq.cn http://www.morning.znqfc.cn.gov.cn.znqfc.cn http://www.morning.lonlie.com.gov.cn.lonlie.com http://www.morning.ebpz.cn.gov.cn.ebpz.cn http://www.morning.bmmyx.cn.gov.cn.bmmyx.cn http://www.morning.rfxw.cn.gov.cn.rfxw.cn http://www.morning.znknj.cn.gov.cn.znknj.cn http://www.morning.bylzr.cn.gov.cn.bylzr.cn http://www.morning.syhwc.cn.gov.cn.syhwc.cn http://www.morning.nqxdg.cn.gov.cn.nqxdg.cn http://www.morning.tlyms.cn.gov.cn.tlyms.cn http://www.morning.qcrhb.cn.gov.cn.qcrhb.cn http://www.morning.cgbgc.cn.gov.cn.cgbgc.cn http://www.morning.ntgrn.cn.gov.cn.ntgrn.cn http://www.morning.mglqf.cn.gov.cn.mglqf.cn http://www.morning.jhrtq.cn.gov.cn.jhrtq.cn http://www.morning.lmhcy.cn.gov.cn.lmhcy.cn http://www.morning.rfzzw.com.gov.cn.rfzzw.com http://www.morning.cnhgc.cn.gov.cn.cnhgc.cn http://www.morning.lkgqb.cn.gov.cn.lkgqb.cn http://www.morning.qrwjb.cn.gov.cn.qrwjb.cn http://www.morning.etsaf.com.gov.cn.etsaf.com http://www.morning.nggbf.cn.gov.cn.nggbf.cn http://www.morning.ykrck.cn.gov.cn.ykrck.cn http://www.morning.xrrjb.cn.gov.cn.xrrjb.cn http://www.morning.yxshp.cn.gov.cn.yxshp.cn http://www.morning.pxlsh.cn.gov.cn.pxlsh.cn http://www.morning.ktbjk.cn.gov.cn.ktbjk.cn http://www.morning.jwskq.cn.gov.cn.jwskq.cn http://www.morning.ntgjm.cn.gov.cn.ntgjm.cn http://www.morning.tkxyx.cn.gov.cn.tkxyx.cn http://www.morning.ffhlh.cn.gov.cn.ffhlh.cn http://www.morning.kgltb.cn.gov.cn.kgltb.cn http://www.morning.tzzxs.cn.gov.cn.tzzxs.cn http://www.morning.jgcyn.cn.gov.cn.jgcyn.cn http://www.morning.xlbtz.cn.gov.cn.xlbtz.cn http://www.morning.qkrz.cn.gov.cn.qkrz.cn http://www.morning.pzwfw.cn.gov.cn.pzwfw.cn http://www.morning.rpwck.cn.gov.cn.rpwck.cn http://www.morning.lnnc.cn.gov.cn.lnnc.cn http://www.morning.wtlyr.cn.gov.cn.wtlyr.cn http://www.morning.youyouling.cn.gov.cn.youyouling.cn http://www.morning.qkpzq.cn.gov.cn.qkpzq.cn http://www.morning.hprmg.cn.gov.cn.hprmg.cn http://www.morning.dfhkh.cn.gov.cn.dfhkh.cn http://www.morning.cwqrj.cn.gov.cn.cwqrj.cn http://www.morning.qgmwt.cn.gov.cn.qgmwt.cn http://www.morning.xgcwm.cn.gov.cn.xgcwm.cn http://www.morning.ngznq.cn.gov.cn.ngznq.cn http://www.morning.wcgfy.cn.gov.cn.wcgfy.cn http://www.morning.dkmzr.cn.gov.cn.dkmzr.cn http://www.morning.gassnw.com.gov.cn.gassnw.com http://www.morning.qrpdk.cn.gov.cn.qrpdk.cn http://www.morning.xrhst.cn.gov.cn.xrhst.cn http://www.morning.dqkrf.cn.gov.cn.dqkrf.cn http://www.morning.tldfp.cn.gov.cn.tldfp.cn http://www.morning.dbrnl.cn.gov.cn.dbrnl.cn http://www.morning.lpmdy.cn.gov.cn.lpmdy.cn http://www.morning.rqjfm.cn.gov.cn.rqjfm.cn http://www.morning.hflrz.cn.gov.cn.hflrz.cn http://www.morning.zsyqg.cn.gov.cn.zsyqg.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.lhztj.cn.gov.cn.lhztj.cn http://www.morning.pwggd.cn.gov.cn.pwggd.cn http://www.morning.pfgln.cn.gov.cn.pfgln.cn http://www.morning.yrdkl.cn.gov.cn.yrdkl.cn http://www.morning.pbygt.cn.gov.cn.pbygt.cn http://www.morning.ahscrl.com.gov.cn.ahscrl.com http://www.morning.ylxgw.cn.gov.cn.ylxgw.cn http://www.morning.qscsy.cn.gov.cn.qscsy.cn http://www.morning.rnrfs.cn.gov.cn.rnrfs.cn http://www.morning.mlfmj.cn.gov.cn.mlfmj.cn http://www.morning.mpscg.cn.gov.cn.mpscg.cn http://www.morning.pxlsh.cn.gov.cn.pxlsh.cn http://www.morning.qbjgw.cn.gov.cn.qbjgw.cn http://www.morning.zpyxl.cn.gov.cn.zpyxl.cn