From 9dbf9c9681edf42ed5ff38594c2d568ff3e700dc Mon Sep 17 00:00:00 2001 From: mdn-bot <108879845+mdn-bot@users.noreply.github.com> Date: Tue, 2 Jul 2024 01:29:27 +0000 Subject: [PATCH 1/5] zh-cn: sync translated content --- files/zh-cn/_redirects.txt | 1 + files/zh-cn/_wikihistory.json | 8 ++++---- .../javascript/building_blocks/event_bubbling}/index.md | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) rename files/zh-cn/{web/api/event/comparison_of_event_targets => learn/javascript/building_blocks/event_bubbling}/index.md (98%) diff --git a/files/zh-cn/_redirects.txt b/files/zh-cn/_redirects.txt index cf3da9a7daed40..5d555b258605bf 100644 --- a/files/zh-cn/_redirects.txt +++ b/files/zh-cn/_redirects.txt @@ -1470,6 +1470,7 @@ /zh-CN/docs/Web/API/Element/pointerlockchange_event /zh-CN/docs/Web/API/Document/pointerlockchange_event /zh-CN/docs/Web/API/Element/removeAttributre /zh-CN/docs/Web/API/Element/removeAttribute /zh-CN/docs/Web/API/Element/select_event /zh-CN/docs/Web/API/HTMLInputElement/select_event +/zh-CN/docs/Web/API/Event/Comparison_of_Event_Targets /zh-CN/docs/Learn/JavaScript/Building_blocks/Event_bubbling /zh-CN/docs/Web/API/Event/CustomEvent /zh-CN/docs/Web/API/CustomEvent /zh-CN/docs/Web/API/Event/pageY /zh-CN/docs/Web/API/MouseEvent/pageY /zh-CN/docs/Web/API/Event/禁用时间冒泡 /zh-CN/docs/Web/API/Event/cancelBubble diff --git a/files/zh-cn/_wikihistory.json b/files/zh-cn/_wikihistory.json index 9d8dcc3e38b795..0188b12a688df3 100644 --- a/files/zh-cn/_wikihistory.json +++ b/files/zh-cn/_wikihistory.json @@ -3557,6 +3557,10 @@ "ppphp" ] }, + "Learn/JavaScript/Building_blocks/Event_bubbling": { + "modified": "2019-03-18T21:17:15.255Z", + "contributors": ["zhuangyin"] + }, "Learn/JavaScript/Building_blocks/Events": { "modified": "2020-08-04T06:06:58.173Z", "contributors": [ @@ -9177,10 +9181,6 @@ "TigerSoldier" ] }, - "Web/API/Event/Comparison_of_Event_Targets": { - "modified": "2019-03-18T21:17:15.255Z", - "contributors": ["zhuangyin"] - }, "Web/API/Event/Event": { "modified": "2020-10-15T21:37:04.498Z", "contributors": [ diff --git a/files/zh-cn/web/api/event/comparison_of_event_targets/index.md b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md similarity index 98% rename from files/zh-cn/web/api/event/comparison_of_event_targets/index.md rename to files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md index 40cf37237cbdb1..20bfdace349442 100644 --- a/files/zh-cn/web/api/event/comparison_of_event_targets/index.md +++ b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md @@ -1,6 +1,7 @@ --- title: Comparison of Event Targets -slug: Web/API/Event/Comparison_of_Event_Targets +slug: Learn/JavaScript/Building_blocks/Event_bubbling +original_slug: Web/API/Event/Comparison_of_Event_Targets --- {{ ApiRef() }} From 7e1c3aa57e6137e446a0a23d48ed7e8f4f44a6c4 Mon Sep 17 00:00:00 2001 From: Jason Ren <40999116+jasonren0403@users.noreply.github.com> Date: Tue, 2 Jul 2024 07:30:07 +0000 Subject: [PATCH 2/5] resolve flaws --- .../building_blocks/event_bubbling/index.md | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md index 20bfdace349442..12ea97f72f308c 100644 --- a/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md +++ b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md @@ -1,10 +1,9 @@ --- -title: Comparison of Event Targets +title: 事件冒泡 slug: Learn/JavaScript/Building_blocks/Event_bubbling -original_slug: Web/API/Event/Comparison_of_Event_Targets --- -{{ ApiRef() }} +{{LearnSidebar}}{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Events","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}} ### Event targets @@ -20,10 +19,10 @@ There are 5 targets to consider: Purpose - event.target + event.target DOM Event Interface @@ -37,22 +36,22 @@ There are 5 targets to consider: - event.currentTarget + event.currentTarget DOM Event Interface The EventTarget whose EventListeners are currently being processed. As the event capturing and bubbling @@ -60,10 +59,10 @@ There are 5 targets to consider: - event.relatedTarget + event.relatedTarget DOM MouseEvent Interface @@ -71,7 +70,7 @@ There are 5 targets to consider: - event.explicitOriginalTarget @@ -94,7 +93,7 @@ There are 5 targets to consider: - event.originalTarget + event.originalTarget Date: Tue, 2 Jul 2024 07:50:22 +0000 Subject: [PATCH 3/5] separate bubbling and event main docs --- .../building_blocks/event_bubbling/index.md | 538 +++++++++++------- .../building_blocks/events/index.md | 357 +----------- 2 files changed, 348 insertions(+), 547 deletions(-) diff --git a/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md index 12ea97f72f308c..5c6311e9a2771f 100644 --- a/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md +++ b/files/zh-cn/learn/javascript/building_blocks/event_bubbling/index.md @@ -5,206 +5,360 @@ slug: Learn/JavaScript/Building_blocks/Event_bubbling {{LearnSidebar}}{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Events","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}} -### Event targets - -It's easy to get confused about which target to examine when writing an event handler. This article should clarify the use of the target properties. - -There are 5 targets to consider: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyDefined inPurpose
event.target - DOM Event Interface - -

- The DOM element on the lefthand side of the call that triggered this - event, eg: -

-
element.dispatchEvent(event)
-
-
event.currentTarget - DOM Event Interface - - The - EventTarget - whose - EventListeners - are currently being processed. As the event capturing and bubbling - occurs this value changes. -
event.relatedTarget - DOM MouseEvent Interface - Identifies a secondary target for the event.
- event.explicitOriginalTarget - - Event.webidl - - {{ Non-standard_inline() }} If the event was retargeted for - some reason other than an anonymous boundary crossing, this will be set - to the target before the retargeting occurs. For example, mouse events - are retargeted to their parent node when they happen over text nodes - ([Firefox bug 185889](https://bugzil.la/185889)), and in that case .target will - show the parent and .explicitOriginalTarget will show the - text node.
Unlike .originalTarget, - .explicitOriginalTarget will never contain anonymous - content. -
event.originalTarget - Event.webidl - - {{ Non-standard_inline() }} The original target of the event, - before any retargetings. See - Anonymous Content#Event_Flow_and_Targeting - for details. -
- -### Use of `explicitOriginalTarget` and `originalTarget` - -TODO: Only available in a Mozilla-based browser? TODO: Only suitable for extension-developers? - -### Examples - -``` - - - - - - Comparison of Event Targets - - +## 事件冒泡 + +事件冒泡描述了浏览器如何处理针对嵌套元素的事件。 + +### 在父元素上设置监听器 + +考虑像这样的网页: + +```html +
+ +
+

+```
+
+这里有一个在其他元素({{HTMLElement("div")}})内部的按钮,可以说这里的 `
` 元素是其中包含元素的**父元素**。当我们在父元素附加单击事件处理器,并点击按钮时,会发生什么? + +```js +const output = document.querySelector("#output"); +function handleClick(e) { + output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\n`; +} + +const container = document.querySelector("#container"); +container.addEventListener("click", handleClick); +``` + +{{ EmbedLiveSample('在父元素上设置监听器', '100%', 200, "", "") }} + +你会发现在用户单击按钮时,父元素上触发了单击事件: + +``` +你在 DIV 元素上进行了点击 +``` + +这是有道理的:按钮在 `
` 里面,所以当你点击按钮的时候,你也隐含地点击了它所在的元素。 + +### 冒泡示例 + +如果在按钮*及*其父元素上同时添加事件处理器,会发生什么? + +```html + +
+ +
+

+
+```
+
+让我们试着给按钮、它的父元素(`
`)以及包含它们的 {{HTMLElement("body")}} 元素添加点击事件处理器: + +```js +const output = document.querySelector("#output"); +function handleClick(e) { + output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\n`; +} + +const container = document.querySelector("#container"); +const button = document.querySelector("button"); + +document.body.addEventListener("click", handleClick); +container.addEventListener("click", handleClick); +button.addEventListener("click", handleClick); +``` + +{{ EmbedLiveSample('冒泡', '100%', 200, "", "") }} + +你会发现在用户单击按钮时,所有三个元素都触发了单击事件: + +``` +你在 BUTTON 元素上进行了点击 +你在 DIV 元素上进行了点击 +你在 BODY 元素上进行了点击 +``` + +在这种情况下: + +- 最先触发按钮上的单击事件 +- 然后是按钮的父元素(`
` 元素) +- 然后是 `
` 的父元素(`` 元素) + +我们可以这样描述:事件从被点击的最里面的元素**冒泡**而出。 + +这种行为可能是有用的,也可能引起意想不到的问题。在接下来的章节中,我们将看到它引起的一个问题,并找到解决方案。 + +### 视频播放器示例 + +在这个示例中,我们的页面包含一个视频,最初它为隐藏状态;还有一个标记为“显示视频”的按钮。我们希望有如下交互: + +- 当用户单击“显示视频”按钮时,显示包含视频的盒子,但不要开始播放视频。 +- 当用户在视频上单击时,开始播放视频。 +- 当用户单击盒子内视频以外的任何区域时,隐藏盒子。 + +HTML 代码看起来像这样: + +```html + + + +``` + +它包含: + +- 一个 ` + + +``` + +```css hidden +div { + width: 100%; + height: 100%; + background-color: #eee; +} + +.hidden { + display: none; +} + +div video { + padding: 40px; + display: block; + width: 400px; + margin: 40px auto; +} +``` + +### 事件捕获 + +事件传播的另一种形式是*事件捕获*。这就像事件冒泡,但顺序是相反的:事件不是先在最内层的目标元素上发生,然后在连续较少的嵌套元素上发生,而是先在*最小嵌套*元素上发生,然后在连续更多的嵌套元素上发生,直到达到目标。 + +事件捕获默认是禁用的,你需要在 `addEventListener()` 的 `capture` 选项中启用它。 + +以下示例类似于之前看到的[冒泡示例](#冒泡示例),除了使用了 `capture` 选项以外: + +```html - - - - - - - - - - - - - - - - - -
Original target dispatching the event event.targetTarget who's event listener is being processed event.currentTargetIdentify other element (if any) involved in the event event.relatedTargetIf there was a retargetting of the event for some reason event.explicitOriginalTarget contains the target before retargetting (never contains anonymous targets)If there was a retargetting of the event for some reason event.originalTarget contains the target before retargetting (may contain anonymous targets)
-

Clicking on the text will show the difference between explicitOriginalTarget, originalTarget and target

- +
+ +
+

 
-
 ```
 
-### Use of `target` and `relatedTarget`
+```js
+const output = document.querySelector("#output");
+function handleClick(e) {
+  output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\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);
+```
+
+{{ EmbedLiveSample('事件捕获', '100%', 200, "", "") }}
+
+在这种情况下,消息出现的顺序发生了颠倒:`` 事件处理器首先触发,然后是 `
` 的,最后是 ` -
-

-```
-
-这里有一个在其他元素({{HTMLElement("div")}})内部的按钮,可以说这里的 `
` 元素是其中包含元素的**父元素**。当我们在父元素附加单击事件处理器,并点击按钮时,会发生什么? - -```js -const output = document.querySelector("#output"); -function handleClick(e) { - output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\n`; -} - -const container = document.querySelector("#container"); -container.addEventListener("click", handleClick); -``` - -{{ EmbedLiveSample('在父元素上设置监听器', '100%', 200, "", "") }} - -你会发现在用户单击按钮时,父元素上触发了单击事件: - -``` -你在 DIV 元素上进行了点击 -``` - -这是有道理的:按钮在 `
` 里面,所以当你点击按钮的时候,你也隐含地点击了它所在的元素。 - -### 冒泡示例 - -如果在按钮*及*其父元素上同时添加事件处理器,会发生什么? - -```html - -
- -
-

-
-```
-
-让我们试着给按钮、它的父元素(`
`)以及包含它们的 {{HTMLElement("body")}} 元素添加点击事件处理器: - -```js -const output = document.querySelector("#output"); -function handleClick(e) { - output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\n`; -} - -const container = document.querySelector("#container"); -const button = document.querySelector("button"); - -document.body.addEventListener("click", handleClick); -container.addEventListener("click", handleClick); -button.addEventListener("click", handleClick); -``` - -{{ EmbedLiveSample('冒泡', '100%', 200, "", "") }} - -你会发现在用户单击按钮时,所有三个元素都触发了单击事件: - -``` -你在 BUTTON 元素上进行了点击 -你在 DIV 元素上进行了点击 -你在 BODY 元素上进行了点击 -``` - -在这种情况下: - -- 最先触发按钮上的单击事件 -- 然后是按钮的父元素(`
` 元素) -- 然后是 `
` 的父元素(`` 元素) - -我们可以这样描述:事件从被点击的最里面的元素**冒泡**而出。 - -这种行为可能是有用的,也可能引起意想不到的问题。在接下来的章节中,我们将看到它引起的一个问题,并找到解决方案。 - -### 视频播放器示例 - -在这个示例中,我们的页面包含一个视频,最初它为隐藏状态;还有一个标记为“显示视频”的按钮。我们希望有如下交互: - -- 当用户单击“显示视频”按钮时,显示包含视频的盒子,但不要开始播放视频。 -- 当用户在视频上单击时,开始播放视频。 -- 当用户单击盒子内视频以外的任何区域时,隐藏盒子。 - -HTML 代码看起来像这样: - -```html - - - -``` - -它包含: - -- 一个 ` - - -``` - -```css hidden -div { - width: 100%; - height: 100%; - background-color: #eee; -} - -.hidden { - display: none; -} - -div video { - padding: 40px; - display: block; - width: 400px; - margin: 40px auto; -} -``` - -### 事件捕获 - -事件传播的另一种形式是*事件捕获*。这就像事件冒泡,但顺序是相反的:事件不是先在最内层的目标元素上发生,然后在连续较少的嵌套元素上发生,而是先在*最小嵌套*元素上发生,然后在连续更多的嵌套元素上发生,直到达到目标。 - -事件捕获默认是禁用的,你需要在 `addEventListener()` 的 `capture` 选项中启用它。 - -以下示例类似于之前看到的[冒泡示例](#冒泡示例),除了使用了 `capture` 选项以外: - -```html - -
- -
-

-
-```
-
-```js
-const output = document.querySelector("#output");
-function handleClick(e) {
-  output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\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);
-```
-
-{{ EmbedLiveSample('事件捕获', '100%', 200, "", "") }}
-
-在这种情况下,消息出现的顺序发生了颠倒:`` 事件处理器首先触发,然后是 `
` 的,最后是 `