diff --git a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md index fd5d260fa8..202a43bf8f 100644 --- a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md +++ b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/solution.md @@ -1,16 +1,16 @@ -当浏览器读取如 `onclick` 这样的 `on*` 属性时,它会根据内容创建一个处理程序。 +当浏览器读取诸如 `onclick` 之类的 `on*` 特性(attribute)时,浏览器会根据其内容创建对应的处理程序。 -对 `onclick="handler()"` 来说函数是: +对于 `onclick="handler()"` 来说,函数是: ```js function(event) { - handler() // the content of onclick + handler() // onclick 的内容 } ``` -现在我们可以看到 `handler()` 返回值没有被使用,也没有对结果产生影响。 +现在我们可以看到 `handler()` 的返回值并没有被使用,也没有对结果产生影响。 -修复方法很简单: +修复起来很简单: ```html run -w3.org +w3.org ``` -也可以像这样使用 `event.preventDefault()`: +我们也可以使用 `event.preventDefault()`,像这样: ```html run -w3.org +w3.org ``` diff --git a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md index b9648b402a..806f64bb65 100644 --- a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md +++ b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md @@ -4,7 +4,7 @@ importance: 3 # 为什么 "return false" 不起作用? -为什么下述代码 `return false` 不起作用? +为什么下面这段代码中的 `return false` 不起作用? ```html autorun run -the browser will go to w3.org +the browser will go to w3.org ``` -浏览器在单击时会根据 URL 进行跳转,但这不是我们想要的。 +浏览器在点击时会根据 URL 进行跳转,但这不是我们想要的。 -如何修复? +如何修复它? diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md index 2c0afea7af..3038f1af5f 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.md @@ -1,5 +1,5 @@ -这是一个使用事件委托模式的案例。 +这是一个很好的使用事件委托模式的案例。 -在现实中,我们可以向服务器发送一个 "logging" 请求而不是询问,以保存访问者离开位置的信息。或者我们可以加载内容并将其显示在页面中(如果允许的话)。 +在现实生活中,我们可以向服务器发送一个 "logging" 请求而不是询问,该请求会保存关于访问者离开位置的信息。或者,我们可以加载内容,并将其显示在页面中(如果允许的话)。 -我们只需要捕捉 `contents.onclick` 然后使用 `confirm` 来询问用户。一个好主意是使用 `link.getAttribute('href')` 来代替 `link.href`。详情请参阅解决方案。 +我们只需要捕获 `contents.onclick`,然后使用 `confirm` 来询问用户。一个好主意是使用 `link.getAttribute('href')` 来代替 `link.href`。详情请参见解决方案。 diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md index 28f1fb60dc..c5285217a2 100644 --- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md +++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md @@ -2,15 +2,15 @@ importance: 5 --- -# 在元素中捕获链接 +# 捕获元素中的链接 -在所有包含 `id="contents"` 属性元素的链接(在触发单击事件时)询问用户是否真的想离开当前页面。 +使所有包含 `id="contents"` 的元素内的链接询问用户是否真的要离开。如果用户不想离开,那就不离开。 -就像这样: +像这样: [iframe height=100 border=1 src="solution"] 细节: -- 元素中的 HTML 可以随时动态加载或者重新生成,因此我们无法找到所有链接并将处理器放在它们身上。这里使用事件委托。 -- 内容可能有嵌套标签。内部链接也是这样,比如 `...`。 +- 元素内的 HTML 可以被随时动态加载或重新生成,因此,我们无法找到所有链接并为其添加处理程序。这里使用事件委托。 +- 内容中可能有嵌套的标签。链接中也是,例如 `...`。 diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md index f8e5d08b99..7b41513d8b 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.md @@ -1 +1 @@ -解决方案是将处理器分发给容器并追踪点击。如果单击 `` 上的链接,则将 `#largeImg` 的 `src` 修改位缩略图的 `href`。 +解决方案是将处理程序分配给容器,并追踪点击。如果点击在 `` 链接上,则将 `#largeImg` 的 `src` 修改为该缩略图的 `href`。 diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md b/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md index 6aed1a9c78..ef78f789b5 100644 --- a/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md +++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# 图像库 +# 图片库 -创建一个图像库,通过单击缩略图来更改主图像。 +创建一个图片库,通过点击缩略图可以更改主图像。 -就像这样: +像这样: [iframe src="solution" height=600] diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md index b57696907f..0e4a1d705b 100644 --- a/2-ui/2-events/04-default-browser-action/article.md +++ b/2-ui/2-events/04-default-browser-action/article.md @@ -1,23 +1,23 @@ -# 浏览器默认动作 +# 浏览器默认行为 -许多事件会自动触发浏览器动作。 +许多事件会自动触发浏览器执行某些行为。 例如: -- 单击一个链接 —— 触发到它的 URL。 -- 单击表单中的提交按钮 —— 触发提交到服务器的动作。 -- 在文本上按下鼠标按键并移动 —— 选中文本。 +- 点击一个链接 —— 触发导航(navigation)到该 URL。 +- 点击表单的提交按钮 —— 触发提交到服务器的行为。 +- 在文本上按下鼠标按钮并移动 —— 选中文本。 -如果我们用 JavaScript 处理一个事件,我们通常不需要浏览器动作。幸运的是,它是可以阻止的。 +如果我们使用 JavaScript 处理一个事件,那么我们通常不希望发生相应的浏览器行为。而是想要实现其他行为进行替代。 -## 阻止浏览器动作 +## 阻止浏览器行为 -有两种方法可以告诉浏览器我们不希望它执行动作: +有两种方式来告诉浏览器我们不希望它执行默认行为: -- 主流的方法是使用 `event` 对象。有一个 `event.preventDefault()` 方法。 -- 如果使用 `on`(而不是 `addEventListener`)分发处理器,那么我们只需要从它内部返回 `false` 即可。 +- 主流的方式是使用 `event` 对象。有一个 `event.preventDefault()` 方法。 +- 如果处理程序是使用 `on`(而不是 `addEventListener`)分配的,那返回 `false` 也同样有效。 -在下面的示例中,单击链接不会导致 URL 改变: +在下面这个示例中,点击链接不会触发导航(navigation),浏览器不会执行任何操作: ```html autorun height=60 no-beautify Click here @@ -25,12 +25,14 @@ or here ``` -```warn header="没有必要去返回 `true`" -事件处理器返回的值通常会被忽略。 - -唯一的例外 —— 是从使用 `on` 分发的处理器中 `return false`。 +在下一个示例中,我们将使用此技术来创建 JavaScript 驱动的菜单。 -在所有其他情况下,返回都是不需要的,也不需要被处理。 +```warn header="从处理程序返回 `false` 是一个例外" +事件处理程序返回的值通常会被忽略。 + +唯一的例外是从使用 `on` 分配的处理程序中返回的 `return false`。 + +在所有其他情况下,`return` 值都会被忽略。并且,返回 `true` 没有意义。 ``` ### 示例:菜单 @@ -45,78 +47,91 @@ or ``` -下面是一些 CSS 的外观: +下面经过 CSS 渲染的外观: [iframe height=70 src="menu" link edit] -菜单项是 `` 链接,而不是按钮。这有几个好处,比如: +菜单项是通过使用 HTML 链接 `` 实现的,而不是使用按钮 ` + ``` -现在,假设我们用我们自己的选项实现我们自己文档范围的上下文菜单。在文档中,我们可能有其他元素和它们自己的上下文菜单: +现在,除了该上下文菜单外,我们还想实现文档范围的上下文菜单。 + +右键单击时,应该显示最近的上下文菜单: ```html autorun height=80 no-beautify run

Right-click here for the document context menu

@@ -135,9 +150,9 @@ menu.onclick = function(event) { ``` -问题是当我们点击 `elem` 时,我们得到两个菜单:按钮级别(事件冒泡)和文档级别的菜单。 +问题是,当我们点击 `elem` 时,我们会得到两个菜单:按钮级和文档级(事件冒泡)的菜单。 -如何修复呢?其中一个解决方案是:“在按钮处理器中,我们全部去处理(按钮级别的)事件,然后停止它。”还要使用 `event.stopPropagation()`: +如何修复呢?其中一个解决方案是:“当我们在按钮处理程序中处理鼠标右键单击事件时,我们阻止其冒泡”,使用 `event.stopPropagation()`: ```html autorun height=80 no-beautify run

Right-click for the document menu

@@ -159,13 +174,13 @@ menu.onclick = function(event) { ``` -现在按钮级别的菜单如期工作。但是代价太大,我们会永远拒绝访问任何外部代码的右击信息,包括收集统计信息的计数器等等。这很不可取。 +现在按钮级菜单如期工作。但是代价太大,我们永远拒绝访问外部代码中的有关右键单击的信息,包括收集统计信息的计数器等。这是非常不明智的。 -另一个替代方案是,在文档级处理器中去检测默认动作是否被阻止?如果是这样的话,那么事件就被处理了,我们不需要对它做出反应。 +另一个替代方案是,检查 `document` 处理程序是否阻止了浏览器的默认行为?如果阻止了,那么该事件已经得到了处理,我们无需再对此事件做出反应。 ```html autorun height=80 no-beautify run -

Right-click for the document menu (fixed with event.defaultPrevented)

+

Right-click for the document menu (added a check for event.defaultPrevented)

``` -现在一切都可以正常工作了。如果我们有嵌套元素,并且每个元素都有自己的上下文菜单,那么这也是可以运行的。只需确保检查每个 `contextmenu` 处理器中的 `event.defaultPrevented`。 +现在一切都可以正常工作了。如果我们有嵌套的元素,并且每个元素都有自己的上下文菜单,那么这也是可以运行的。只需确保检查每个 `contextmenu` 处理程序中的 `event.defaultPrevented`。 ```smart header="event.stopPropagation() 和 event.preventDefault()" -正如我们所看到的那样,`event.stopPropagation()` 和 `event.preventDefault()`(也被认为是 `return false`)是两种不同的事情。它们之间毫无联系。 +正如我们所看到的,`event.stopPropagation()` 和 `event.preventDefault()`(也被认为是 `return false`)是两个不同的东西。它们之间毫无关联。 ``` -```smart header="嵌套的上下文目录结构" -还有一些实现嵌套上下文菜单的替代方法。其中一个是拥有一个特殊的全局对象,它具有处理 `document.oncontextmenu` 的方法,还允许在其中存储各种“低级”处理器方法。 +```smart header="嵌套的上下文菜单结构" +还有其他实现嵌套上下文菜单的方式。其中之一是拥有一个具有 `document.oncontextmenu` 处理程序的全局对象,以及使我们能够在其中存储其他处理程序的方法。 -对象将捕获任何右击事件,查看存储的处理器并运行相应的处理器。 +该对象将捕获任何右键单击,浏览存储的处理程序并运行适当的处理程序。 -但每一段需要上下文菜单的代码都应该了解该对象,并使用它的帮助,而不是使用自己的 `contextmenu` 处理器。 +但是,每段需要上下文菜单的代码都应该了解该对象,并使用它的帮助,而不是使用自己的 `contextmenu` 处理程序。 ``` ## 总结 -有许多默认浏览器动作: +有很多默认的浏览器行为: - `mousedown` —— 开始选择(移动鼠标进行选择)。 -- 在 `` 上 `click` —— 检查/取消选中的 `input`。 -- `submit` —— 单击 `` 或在表单中通过单击 `key:Enter` 触发该事件,并在其后浏览器提交表单。 -- `wheel` —— 鼠标滚轮事件的滚动将作为默认动作。 -- `keydown` —— 按下按键可能会导致将字符添加到字段,或者触发其他动作。 -- `contextmenu` —— 事件发生在右击时,动作是显示浏览器上下文菜单。 -- ...还有更多... +- 在 `` 上的 `click` —— 选中/取消选中的 `input`。 +- `submit` —— 点击 `` 或者在表单字段中按下 `key:Enter` 键会触发该事件,之后浏览器将提交表单。 +- `keydown` —— 按下一个按键可能会导致将字符添加到字段,或者触发其他行为。 +- `contextmenu` —— 事件发生在鼠标右键单击时,触发的行为是显示浏览器上下文菜单。 +- ……还有更多…… + +如果我们只想通过 JavaScript 来处理事件,那么所有默认行为都是可以被阻止的。 -如果我们想要通过 JavaScript 来处理事件,那么所有的默认动作都可以被阻止。 +想要阻止默认行为 —— 可以使用 `event.preventDefault()` 或 `return false`。第二个方法只适用于通过 `on` 分配的处理程序。 -想要阻止默认行为 —— 可以使用 `event.preventDefault()` 或者 `return false`。第二个方法只适用于分发了 `on` 的处理器。 +`addEventListener` 的 `passive: true` 选项告诉浏览器该行为不会被阻止。这对于某些移动端的事件(像 `touchstart` 和 `touchmove`)很有用,用以告诉浏览器在滚动之前不应等待所有处理程序完成。 -如果默认动作被阻止,`event.defaultPrevented` 的值就会变成 `true`,否则会变成 `false`。 +如果默认行为被阻止,`event.defaultPrevented` 的值会变成 `true`,否则为 `false`。 -```warn header="Stay semantic, don't abuse" -从技术上来说,通过阻止默认动作和添加 JavaScript,我们可以定制任何元素的行为。例如,我们可以使链接 `
` 像按钮一样工作,而按钮 `