Skip to content

Update translation of 2-ui/2-events/01-introduction-browser-events #683

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Mar 25, 2020
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 5

# 点击隐藏

为 `button` 添加 JavaScript ,使我们在点击的时候让 `<div id="text">` 消失
为 `button` 添加 JavaScript 代码,使得 `<div id="text">` 在我们点击该按钮时消失

示例:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
可以在处理器中使用 `this` 来引用自身
可以在处理程序中使用 `this` 来引用“元素自身”

```html run height=50
<input type="button" onclick="this.hidden=true" value="Click to hide">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 5

# 隐藏自己

创建一个按钮,在单击时,隐藏自己。
创建一个按钮,在被单击时,隐藏自己。

```online
就像这样:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
答案:`1` 和 `2`。

第一个处理器会触发,因为它没有被 `removeEventListener` 移除。要移除处理器,我们需要传递正确分发的函数。在代码中,传递了一个新的函数,看起来相同,但仍然是另一个函数。
第一个处理程序会触发,因为它没有被 `removeEventListener` 移除。要移除处理程序,我们需要传递正确的所分配的函数。在代码中,传递了一个新的函数,该函数看起来相同,但仍然是另一个函数。

要移除函数对象,我们需要存储对它的引用,就像这样
要移除一个函数对象,我们需要存储对它的引用,像这样

```js
function handler() {
Expand All @@ -13,4 +13,4 @@ button.addEventListener("click", handler);
button.removeEventListener("click", handler);
```

处理器 `button.onclick` 独立于 `addEventListener` 之外工作
无论 `addEventListener` 怎样,`button.onclick` 处理程序都会触发
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# 哪一个处理器会运行
# 哪个处理程序会运行

变量中有一个按钮,上面没有处理器
在变量中有一个按钮。它上面没有处理程序

在下面代码之后单击哪些处理器会运行?会出现哪些警报
执行以下代码之后,哪些处理程序会在按钮被点击时运行?会显示哪些 alert

```js no-beautify
button.addEventListener("click", () => alert("1"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

首先我们需要选择一种定位球的方法
首先,我们需要选择一种定位球的方法

我们不能使用 `position:fixed`,因为滑动页面会让球在球场上移动
我们不能使用 `position:fixed`,因为滚动页面会造成球被移出球场

因此我们应该使用 `position:absolute`,并使定位稳定,让 `field` 自身定位
所以我们应该使用 `position:absolute`,并且要使定位真正可靠,应该使 `field` 自身具有 `position:absolute`

然后球会相对于球场定位
然后,球将相对于球场定位

```css
#field {
Expand All @@ -16,36 +16,36 @@

#ball {
position: absolute;
left: 0; /* 相对于最近位置的祖先(字段) */
left: 0; /* 相对于最接近的祖先(field) */
top: 0;
transition: 1s all; /* 在左上方的 CSS 特效会让球飞起来 */
transition: 1s all; /* left/top 的 CSS 动画,使球飞起来 */
}
```

接下来我们需要指定正确的 `ball.style.position.left/top`。它们现在包含球场的相对坐标
接下来我们需要指定正确的 `ball.style.left/top`。它们现在包含相对于球场的坐标

这是图片
这是示意图

![](move-ball-coords.svg)

我们有 `event.clientX/clientY`—— 单击窗口时的相对坐标
我们有 `event.clientX/clientY` —— 单击位置的窗口相对坐标

要获取单击字段的相对 `left` 坐标,我们可以减去字段的左边缘和边框宽度
要获取单击位置的球场相对坐标 `left`,我们可以减去球场左边缘和边框的宽度

```js
let left = event.clientX - fieldInnerCoords.left - field.clientLeft;
let left = event.clientX - fieldCoords.left - field.clientLeft;
```

通常情况下,`ball.style.position.left` 是指“元素的左边缘”(球)。因此,如果我们指定 `left`,那么球的边缘就会在鼠标光标下面
通常情况下,`ball.style.left` 表示“元素的左边缘”(球)。因此,如果我们将其指定为 `left`,那么球的边缘而非球的中心将位于鼠标光标下方

我们需要将球向左移动宽度的一半,向上移动高度的一半,使其居中
我们需要将球向左移动球宽度的一半,向上移动球高度的一半,以使其居中

因此,最后 `left`
所以,最后的 `left` 将是

```js
let left = event.clientX - fieldInnerCoords.left - field.clientLeft - ball.offsetWidth/2;
let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;
```

使用相同的逻辑计算垂直坐标
使用相同的逻辑来计算垂直坐标

请注意,球的宽度/高度必须在我们设置 `ball.offsetWidth` 时就已知。应该在 HTML 或 CSS 中指定。
请注意,球的宽度/高度必须在我们访问 `ball.offsetWidth` 时就已知。应该在 HTML 或 CSS 中指定。
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ importance: 5

# 让球在球场中移动

单击一下让球在球场中移动。就像这样:
单击球场中任意一点,让球在球场中移动。就像这样:

[iframe src="solution" height="260" link]

要求:

- 球的中心应该准确的在单击时指针位置的下方(如果可能的话,不越过球场边缘)
- CSS 动画很受欢迎
- 球的中心应该恰好在单击时指针位置的下方(如果在球不越过球场边缘的情况下,能实现的话)
- 最好添加一些 CSS 动画
- 球不能越过场地边界。
- 当页面被滚动时,任何东西都不应该中断
- 页面滚动时,不会有任何中断

注意:

- 代码还应该能在不同的球和球场大小中工作,而不是绑定到任何固定的值
- 代码还应该适用于不同大小的球和球场,而不应该绑定到任何固定值
- 使用 `event.clientX/event.clientY` 属性来获取点击坐标。
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

# HTML/CSS
首先,我们创建 HTML/CSS。

菜单是页面上的一个独立的图形组件,所以最好把它放在一个 DOM 元素中
首先,让我们创建 HTML/CSS

菜单项列表可以分层为列表 `ul/li`
菜单是页面上的一个独立图形组件,所以最好把它放入一个单独的 DOM 元素中

下面是示例的结构:
菜单项的列表可以被作为列表 `ul/li` 列出。

下面是示例结构:

```html
<div class="menu">
Expand All @@ -19,29 +20,29 @@
</div>
```

我们的标题使用 `<span>`,因为 `<div>` 有一个隐式的 `display:block`,它会 100% 的占据水平宽度
我们对标题使用 `<span>`,因为 `<div>` 有一个隐式的 `display:block`,它会占据 100% 的水平宽度

就像这样:

```html autorun height=50
<div style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</div>
```

因此如果我们在它上面设置 `onclick`,就会在文本的右边捕获点击事件
因此,如果我们在它上面设置 `onclick`,那么它也会捕获文本右侧的点击

...但 `<span>` 有一个隐式 `display: inline`,因此它会占据足够的位置来适应所有的文本
……由于 `<span>` 有一个隐式的 `display: inline`,它恰好占据了足以容纳所有文本的位置

```html autorun height=50
<span style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</span>
```

# 切换菜单
# 切换菜单

切换菜单应更改箭头并显示/隐藏菜单列表。

所以这些更改都能被 CSS 完美处理。在 JavaScript 中,我们应该通过添加/移除 `.open` 类来标记菜单的当前状态。
所有这些更改都可以通过 CSS 完美处理。在 JavaScript 中,我们应该通过添加/移除 `.open` 类来标记菜单的当前状态。

没有它,菜单就会关闭
没有它,菜单就会被关闭

```css
.menu ul {
Expand All @@ -58,7 +59,7 @@
}
```

...使用 `.open` 后,箭头会改变,列表会出现:
……有 `.open` 后,箭头会改变,列表会出现:

```css
.menu.open .title::before {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

我们可以使用 `position:absolute`(使 pane `position:relative`)或者 `float:right` 来添加按钮。`float:right` 的好处是按钮永远都不会重叠文本,但是 `position:absolute` 有更多的灵活性,选择权在你手上
我们可以使用 `position:absolute`(并使窗格 `position:relative`)或者 `float:right` 来添加按钮。`float:right` 的好处是按钮永远都不会与文本重叠,但是 `position:absolute` 则提供了更大的自由度。选择权在你自己手上

然后对于每个 pane 来说,代码都是如此
然后,对于每个窗格(pane),代码可以像这样
```js
pane.insertAdjacentHTML("afterbegin", '<button class="remove-button">[x]</button>');
```

然后 `<button>` 变成了 `pane.firstChild`,因此我们可以像这样为它添加处理器
然后 `<button>` 变成了 `pane.firstChild`,因此我们可以像这样为它添加处理程序

```js
pane.firstChild.onclick = () => pane.remove();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ importance: 5

# 添加关闭按钮

有一张消息列表
有一个消息列表

使用 JavaScript 在每条消息的右上角都添加一个按钮
使用 JavaScript 在每条消息的右上角添加一个关闭按钮

结果应该如下所示:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
图像带可以表示为 `ul/li` 图像列表 `<img>`
图像带可以表示为图像 `<img>` 的 `ul/li` 列表

通常情况下,这样的带是很宽的,但我们还是在其周围设置了一个固定大小的 `<div>` 来“剪切”它,因此只会有一部分带是可见的
通常,这样的图像带是很宽的,但我们在其周围放置了一个固定大小的 `<div>` 来“剪切”它,因此,只有图像带的一部分是可见的

![](carousel1.svg)

为了使列表水平显示,我们需要为 `<li>` 应用正确的 CSS 属性,比如 `display: inline-block`。
为了使列表水平显示,我们需要为 `<li>` 应用正确的 CSS 属性,例如 `display: inline-block`。

对于 `<img>` 来说,我们应该调整 `display`,因为默认情况下它是 `inline`。由于在 `inline` 元素下方具有 "letter tails" 而存在额外空间,所以我们可以使用 `display:block` 来移除多余的空间
对于 `<img>` 来说,我们应该调整 `display`,因为默认情况下它是 `inline`。 `inline` 元素下方为 "letter tails" 保留了额外的空间,因此,我们可以使用 `display:block` 来将其删除

我们可以移动 `<ul>` 来进行滚动。有很多方法都可以实现这一点,比如通过修改 `margin-left` 或者(性能更好)使用 `transform: translateX()`:
我们可以移动 `<ul>` 来进行滚动。有很多方法可以实现这一点,例如,通过修改 `margin-left` 或者使用 `transform: translateX()`(性能更好)

![](carousel2.svg)

外部 `<div>` 具有固定的宽度,因此,"extra" 图像可以被剪切
外部的 `<div>` 具有固定的宽度,因此,会裁剪掉“多余”的图像

整个 carousel 是页面是一个自包含的 "graphical component",因为我们最好将其封装成一个单独的 `<div class="carousel">`,并对其设置样式
整个轮播图是页面上的一个独立的“图形组件”,因此我们最好将其包装到一个单独的 `<div class="carousel">` 中,并在其中对其进行样式设置
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ importance: 4

---

# Carousel
# 轮播图

创建一个 "carousel" —— 一条可以通过点击箭头滚动的图像带
创建一个“轮播图(carousel)” —— 一条可以通过点击箭头来滚动图像的图像带

[iframe height=200 src="solution"]

以后,我们可以添加更多的功能:无限滚动,动态加载等。
之后,我们可以为其添加更多功能:无限滚动,动态加载等。

P.S. 对这个任务来说,HTML/CSS 占解决方案的 90%。
P.S. 对于这个任务,HTML/CSS 结构实际上占解决方案的 90%。
Loading