diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index eb6bf3b15b..35f0a888e5 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -7,7 +7,7 @@ **鼠标事件:** - `click` —— 当鼠标点击一个元素时(触摸屏设备会在点击时生成)。 - `contextmenu` —— 当鼠标右键点击一个元素时。 -- `mouseover` / `mouseout` —— 当鼠标光标移入/离开一个元素时。 +- `mouseover` / `mouseout` —— 当鼠标光标移入/移出一个元素时。 - `mousedown` / `mouseup` —— 当在元素上按下/释放鼠标按钮时。 - `mousemove` —— 当鼠标移动时。 diff --git a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md index 6ce6b03ae4..e5f65730a4 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md +++ b/2-ui/3-event-details/1-mouse-events-basics/01-selectable-list/task.md @@ -4,14 +4,15 @@ importance: 5 # 可选列表 -比如在文件管理器中新建一个可选元素的列表。 +创建一个可以选择元素的列表,例如在文件管理器中。 -- 单击列表元素,只选择某个元素(添加 `.selected` 类),取选剩余元素。 -- 如果使用 `key:Ctrl`(Mac 上为 `key:Cmd`)进行单击,则选择将切换到所单击的元素上,但其他元素不会被修改。 +- 点击列表元素,只选择该元素(添加 `.selected` 类),取消选择其他所有元素。 +- 如果点击时,按键 `key:Ctrl`(在 Mac 中为 `key:Cmd`)是被按下的,则选择会被切换到被点击的元素上,但其他元素不会被改动。 示例: [iframe border="1" src="solution" height=180] -P.S. 对于此任务,我们可以假设列表选择仅仅是文本。不存在嵌套标签。 -P.P.S. 防止本地浏览器在单击时选择文本。 +P.S. 对于此任务,我们可以假设列表项是纯文本的。没有嵌套标签。 + +P.P.S. 防止点击时浏览器原生的文本选择。 diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md index 6f9ebe1f32..9ae7921936 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/article.md +++ b/2-ui/3-event-details/1-mouse-events-basics/article.md @@ -1,53 +1,53 @@ # 鼠标事件基础 -鼠标事件不仅来自于 "mouse manipulators",而且还在触摸设备上被模拟,以便可以让它们相互兼容。 +在本章中,我们将详细介绍鼠标事件及其属性。 -在本章,我们将详细介绍鼠标事件及其属性。 +请注意:此类事件不仅可能来自于“鼠标设备”,还可能来自于对此类操作进行了模拟以实现兼容性的其他设备,例如手机和平板电脑。 ## 鼠标事件类型 -我们可以将鼠标事件分成两类:“简单”和“复杂” +我们可以将鼠标事件分成两类:“简单”和“复杂”。 ### 简单事件 -最常用的简单事件是: +最常用的简单事件有: `mousedown/mouseup` -: 在元素上单击/释放鼠标按钮。 +: 在元素上点击/释放鼠标按钮。 `mouseover/mouseout` -: 鼠标指针从一个元素上移入/出。 +: 鼠标指针从一个元素上移入/移出。 `mousemove` -: 鼠标每次移动到元素上时都会触发事件。 +: 鼠标在元素上的每个移动都会触发此事件。 -...还有其他几种事件类型,我们稍后会讨论它们。 +`contextmenu` +: 尝试打开上下文菜单时触发。在最常见的情况下,此事件发生在鼠标右键被按下时。虽然,还有其他打开上下文菜单的方式,例如使用特殊的键盘键,所以它不完全是一个鼠标事件。 + +……还有其他几种事件类型,我们稍后会讨论它们。 ### 复杂事件 `click` -: 如果使用鼠标左键,则在 `mousedown` 及 `mouseup` 相继触发后触发该事件。 - -`contextmenu` -: 如果使用鼠标右键,则在 `mousedown` 后触发。 +: 如果使用的是鼠标左键,则在同一个元素上的 `mousedown` 及 `mouseup` 相继触发后,触发该事件。 `dblclick` -: 在对元素进行双击后触发。 +: 双击一个元素后触发。 -复杂事件是由简单事件组成的,因此理论上我们可以没有它们而运转。但它们的存在却给我们提供了极大的便利。 +复杂事件是由简单事件组成的,因此,从理论上讲,如果没有这些复杂事件,我们也能实现相应的功能。但它们的存在却给我们提供了极大的便利。 ### 事件顺序 -一个动作可能会触发多个事件。 +一个行为可能会触发多个事件。 -比如,在按下鼠标按钮时,单击会首先触发 `mousedown`,然后释放鼠标按钮时,会触发 `mouseup` 和 `click`。 +比如,点击鼠标按钮,在按下鼠标按钮时,点击会首先触发 `mousedown`,然后释放鼠标按钮时,会触发 `mouseup` 和 `click`。 -在单个动作触发多个事件时,它们的顺序是固定的。也就是说会遵循 `mousedown` -> `mouseup` -> `click` 的顺序。事件按照相同的顺序被处理:`onmouseup` 在 `onclick` 运行之前完成。 +在单个动作触发多个事件时,事件的顺序是固定的。也就是说,会遵循 `mousedown` -> `mouseup` -> `click` 的顺序调用处理程序。 ```online -单击以下按钮,你会看到事件。也可以尝试双击。 +点击(译注:即单击)下面的按钮,你会看到事件。并尝试双击它。 -在测试台下面记录所有鼠标事件,如果它们之间有超过 1 秒的延迟,那么它们会被规则分开。 +在测试台下面记录了所有的鼠标事件,如果它们之间的延迟时间超过 1 秒,那么它们会被水平分割线分开。 我们还可以看出 `which` 属性允许检测鼠标按钮。 @@ -56,11 +56,11 @@ ## 获取按钮:which -与单击相关的事件始终具有 `which` 属性,该属性允许获取准确的鼠标按钮。 +与点击相关的事件始终具有 `which` 属性,该属性允许获取确切的鼠标按钮。 -它不用于 `click`和 `contextmenu` 事件,因为前者只发生在左键,而后者只发生在右击。 +它不用于 `click` 和 `contextmenu` 事件,因为前者只在点击左键时发生,而后者只在点击右键时发生。 -但如果我们跟踪 `mousedown` 和 `mouseup`,那么我们就需要它,因为这些事件在任意鼠标按钮按下时都会触发,所以 `which` 允许区分 "right-mousedown" 和 "left-mousedown"。 +但是,如果我们跟踪 `mousedown` 和 `mouseup`,那么我们就需要它,因为这些事件会在任何按钮上触发,所以 `which` 让我们能够区分 "right-mousedown" 和 "left-mousedown"。 有三个可能的值: @@ -68,20 +68,22 @@ - `event.which == 2` —— 中间按钮 - `event.which == 3` —— 右按钮 -中间按钮现在有些特殊,所有很少被使用。 +中间按钮现在有些特殊,很少被使用了。 -## 组合键: shift、alt、ctrl 和 meta +## 组合键:shift,alt,ctrl,meta -所有的鼠标事件都包含有关按下的组合键信息。 +所有的鼠标事件都包含有关按下的组合键的信息。 -属性: +事件属性: -- `shiftKey` -- `altKey` -- `ctrlKey` -- `metaKey` (`key:Cmd` for Mac) +- `shiftKey`:`key:Shift` +- `altKey`:`key:Alt`(或对于 Mac 是 `key:Opt`) +- `ctrlKey`:`key:Ctrl` +- `metaKey`:对于 Mac 是 `key:Cmd` -比如,下述按钮仅仅在 `key:Alt+Shift`+click 上有效: +如果在事件期间按下了相应的键,则它们为 `true`。 + +比如,下面这个按钮仅在 `key:Alt+Shift`+click 时才有效: ```html autorun height=60 @@ -97,89 +99,60 @@ ``` -```warn header="注意:在 Mac 上我们通常使用 `Cmd` 而不是 `Ctrl`" -在 Windows 和 Linux 上修改键是 `key:Alt`、`key:Shift` 和 `key:Ctrl`。在 Mac 上还有:`key:Cmd`,它对应于属性 `metaKey`。 +```warn header="注意:在 Mac 上我们通常使用 `Cmd` 代替 `Ctrl`" +在 Windows 和 Linux 上有 `key:Alt`,`key:Shift` 和 `key:Ctrl`。在 Mac 上还有:`key:Cmd`,它对应于属性 `metaKey`。 + +在大多数情况下,当在 Windows/Linux 上使用 `key:Ctrl` 时,在 Mac 是使用 `key:Cmd`。 -在大多数情况下,当 Windows/Linux 使用 `key:Ctrl` 时,Mac 的用户会使用 `key:Cmd`。因此当 Windows 用户按下 `key:Ctrl+Enter` 或 `key:Ctrl+A` 时,Mac 用户会按下 `key:Cmd+Enter` 或 `key:Cmd+A` 等,大多数 app 使用 `key:Cmd` 而不是 `key:Ctrl`。 +也就说:当 Windows 用户按下 `key:Ctrl+Enter` 或 `key:Ctrl+A` 时,Mac 用户会按下 `key:Cmd+Enter` 或 `key:Cmd+A`,以此类推。 -因此如果我们想支持 `key:Ctrl`+click,那么对于 Mac 用户来说,使用 `key:Cmd`+click 也是有意义的。这对于 Mac 用户来说非常舒服。 +因此,如果我们想支持 `key:Ctrl`+click,那么对于 Mac 应该使用 `key:Cmd`+click。对于 Mac 用户而言,这更舒适。 -即使我们想迫使 Mac 用户使用 `key:Ctrl`+click —— 也非常困难。问题在于:Mac 上左击 `key:Ctrl` 被解释为**右击**,它会生成 `contextmenu` 事件,而不是像 Windows/Linxu 的 `click` 事件。 +即使我们想强制 Mac 用户使用 `key:Ctrl`+click —— 这非常困难。问题是:在 MacOS 上左键单击和 `key:Ctrl` 一起使用会被解释为 **右键单击**,并且会生成 `contextmenu` 事件,而不是像 Windows/Linux 中的 `click` 事件。 -因此如果我们想让所有操作系统的用户感觉舒适,那么我们应该和 `ctrlKey` 一起使用 `metaKey`。 +因此,如果我们想让所有操作系统的用户都感到舒适,那么我们应该将 `ctrlKey` 与 `metaKey` 一起进行检查。 对于 JS 代码,这意味着我们应该检查 `if (event.ctrlKey || event.metaKey)`。 ``` ```warn header="还有移动设备" -键盘组合是工作流的一个补充。所以如果用户使用键盘操作 —— 它也能工作。 -如果你的设备没有 —— 那么还有另一个方法也可以实现。 +键盘组合是工作流的一个补充。这样,如果访客使用键盘操作 —— 它就会起作用。而且,如果访客的设备没有键盘 —— 那么这里应该有另一种方法来做到这一点。 ``` ## 坐标:clientX/Y,pageX/Y 所有的鼠标事件都有两种形式的坐标: -1. 对于窗口而言:`clientX` 和 `clientY`。 -2. 对于文档而言:`pageX` 和 `pageY`。 +1. 相对于窗口的坐标:`clientX` 和 `clientY`。 +2. 相对于文档的坐标:`pageX` 和 `pageY`。 -比如,如果我们有一个 500 x 500 的窗口,鼠标在左上方,那么 `clientX` 和 `clientY` 都是 `0`。如果鼠标在中间,那么 `clientX` 和 `clientY` 就是 `250`。和它在文档中的位置无关。它们类似于 `position:fixed`。 +比如,如果我们有一个大小为 500x500 的窗口,并且鼠标在左上角,那么 `clientX` 和 `clientY` 均为 `0`。如果鼠标位于中间,那么 `clientX` 和 `clientY` 均为 `250`。这与它在文档中的位置无关。它们类似于 `position:fixed`。 ````online -将鼠标移动到输入字段上,可以看到 `clientX/clientY`(它在 `iframe` 中,因此坐标是相对于 `iframe` 而言的): +将鼠标移动到输入字段上,可以看到 `clientX/clientY`(此示例位于 `iframe` 中,因此坐标是相对于 `iframe` 的): ```html autorun height=50 ``` ```` -文档相对坐标是从文档的左上角而不是窗口中计算出来的。 -坐标 `pageX`,`pageY` 与文档级别上的 `position:absolute` 非常相似。 - -你可以在本章中阅读到更多关于坐标的内容 。 - -## Mousedown 没有选择 +文档相对坐标 `pageX` 和 `pageY` 是从文档的左上角而不是窗口开始计算的。你可以在 一章中阅读有关坐标的更多细节。 -鼠标点击有一个让人不安的副作用。双击可以选择文本。 +## 禁用选择 -如果我们想自己处理点击事件,那么“额外”的选择就显得多余了。 +双击鼠标会有副作用,在某些界面中可能会出现干扰:它会选择文本。 -比如,对下面的文本双击,除了我们的触发事件之外,还会选择文本: +比如,双击下面的文本,除了我们的处理程序外,还会选择文本: ```html autorun height=50 -Double-click me -``` - -还有 CSS 方法可以终止选择:[CSS UI 草案](https://www.w3.org/TR/css-ui-4/) 中的 `user-select` 属性。 - -大多数浏览器都支持它的前缀: - -```html autorun height=50 - - -Before... - - Unselectable - -...After +Double-click me ``` -如果现在你双击“不可选”,它就不会被选中了。看起来好像起作用了。 - -...但有一个潜在的问题!文本变得无法被选中。即使用户从“之前”开始选择,“之后”结束,选择也会跳过“不可选择”部分。我们真的想让文本不可选么? - -大部分时间,我们不会那么做。用户可能有合理的理由来选择文本,以便进行复制或其他需要。如果我们不让他那么做那么可能不太方便。所以这个解决方案没那么好。 +如果按下鼠标左键,并在不松开的情况下移动鼠标,这也常常会造成不必要的选择。 -我们只是想阻止双击进行选择,仅此而已。 +有多种防止选择的方法,你可以在 一章中详细阅读。 -文本选择是 `mousedown` 事件的默认浏览器操作。因此其他比较好的解决方案是处理 `mousedown` 并阻止它发生,就像这样: +在这种情况下,最合理的方式是防止浏览器对 `mousedown` 进行操作。这样能够阻止刚刚提到的两种选择: ```html autorun height=50 Before... @@ -189,28 +162,12 @@ Before... ...After ``` -现在,在双击时不选择粗体元素。 +现在,在双击时,粗体元素不会被选中,并且在粗体元素上按下鼠标左键也不会开始选择。 -内部文字仍然可以被选中。但选择却不应该从文本自身开始,而是应该在文字之前或之后开始。通常情况下,都是正常的。 - -````smart header="取消选择" -我们可以在事件处理器中用 "post-factum" 取消它,而不是**阻止**选择它。 - -这是方法: - -```html autorun height=50 -Before... - - Double-click me - -...After -``` - -如果你双击粗体元素,则会出现所选内容,然后立即删除,不过看起来不太好。 -```` +请注意:其中的文本仍然是可选择的。但是,选择不应该开始于该文本自身,而应该在该文本之前或之后开始。通常,这对用户来说挺好的。 ````smart header="防止复制" -如果我们想要禁用选择以保护内容不被复制粘贴,那么我们可以使用另一个事件:`oncopy`。 +如果我们想禁用选择以保护我们页面的内容不被复制粘贴,那么我们可以使用另一个事件:`oncopy`。 ```html autorun height=80 no-beautify
@@ -219,25 +176,22 @@ Before... If you know JS or HTML, then you can get everything from the page source though.
``` -如果你试图在 `
` 中复制一段文本,这是行不通的,因为默认操作 `oncopy` 是被阻止的。 +如果你试图在 `
` 中复制一段文本,这是行不通的,因为默认行为 `oncopy` 被阻止了。 -当然,这不能阻止用户打开 HTML 源代码,但并不是每个人都知道如何做到这一点。 +当然,用户可以访问页面的 HTML 源码,并且可以从那里获取内容,但并不是每个人都知道如何做到这一点。 ```` ## 总结 -鼠标事件有如下属性: +鼠标事件有以下属性: - 按钮:`which`。 -- 修饰符键(`true` 如果被按压):`altKey`、`ctrlKey`、`shiftKey` 和 `metaKey`(Mac)。 - - 如果想要处理 `key:Ctrl`,那么不要忘记 Mac 用户,他们使用的是 `key:Cmd`,所以最好检查 `if (e.metaKey || e.ctrlKey)`。 +- 组合键(如果被按下则为 `true`):`altKey`,`ctrlKey`,`shiftKey` 和 `metaKey`(Mac)。 + - 如果你想处理 `key:Ctrl`,那么不要忘记 Mac 用户,他们通常使用的是 `key:Cmd`,所以最好检查 `if (e.metaKey || e.ctrlKey)`。 - 窗口相对坐标:`clientX/clientY`。 - 文档相对坐标:`pageX/pageY`。 -处理文本选择虽然也是不必要的点击副作用,但是却很重要。 +`mousedown` 的默认浏览器操作是文本选择,如果它对界面不利,则应避免它。 -还有几种可以做到这一点的方法,比如: -1. CSS 属性 `user-select:none`(带有浏览器前缀)完全禁用文本选择。 -2. 使用 `getSelection().removeAllRanges()` 取消选择后的内容。 -3. 处理 `mousedown` 并阻止默认操作(通常是最好的选择)。 +在下一章中,我们将看到有关指针移动后的事件,以及如何跟踪其下元素变化的更多详细信息。 diff --git a/2-ui/3-event-details/index.md b/2-ui/3-event-details/index.md index c30fb70645..81bd1a9cf8 100644 --- a/2-ui/3-event-details/index.md +++ b/2-ui/3-event-details/index.md @@ -1,3 +1,3 @@ -# 事件细节 +# UI 事件 -这里我们介绍最重要的事和它们运行的细节。 +在这里,我们介绍了最重要的用户界面事件,以及如何使用它们。