Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Answer: **1 and 3**.
回答:**1 3**

Both commands result in adding the `text` "as text" into the `elem`.
所有命令行都是将 `text` “作为文本”添加到 `elem`

Here's an example:
这里有个简单的例子:

```html run height=80
<div id="elem1"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# createTextNode vs innerHTML vs textContent
# 对比 createTextNode、innerHTML textContent

We have an empty DOM element `elem` and a string `text`.
我们有一个空的 DOM 元素 `elem` 和一个字符串 `text`

Which of these 3 commands do exactly the same?
以下这三个命令行的结果是一样的吗?

1. `elem.append(document.createTextNode(text))`
2. `elem.innerHTML = text`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
First, let's make HTML/CSS.
首先,使用 HTML/CSS

Each component of the time would look great in its own `<span>`:
每个时间组件在`<span>`标签中看起来很棒:

```html
<div id="clock">
<span class="hour">hh</span>:<span class="min">mm</span>:<span class="sec">ss</span>
</div>
```

Also we'll need CSS to color them.
我们还会用 CSS 丰富样式。

The `update` function will refresh the clock, to be called by `setInterval` every second:
`update` 会刷新时钟,它调用 `setInterval` 每秒刷新一次:

```js
function update() {
Expand All @@ -32,9 +32,9 @@ function update() {
}
```

In the line `(*)` we every time check the current date. The calls to `setInterval` are not reliable: they may happen with delays.
在这行 `(*)` 我们每秒检查当前时间。调用 `setInterval` 并不是完全可靠:它有可能发生延迟现象。

The clock-managing functions:
时钟管理函数:

```js
let timerId;
Expand All @@ -50,4 +50,4 @@ function clockStop() {
}
```

Please note that the call to `update()` is not only scheduled in `clockStart()`, but immediately run in the line `(*)`. Otherwise the visitor would have to wait till the first execution of `setInterval`. And the clock would be empty till then.
请留意 `update()`,它不单在 `clockStart()` 被间隔器调用,也会在 `(*)` 立即调用一次。如果不是这样,只有在 `setInterval` 第一次执行周期时,才能看到时钟,在此之前时钟一直都是空的。
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ importance: 4

---

# Colored clock with setInterval
# setInterval 的彩色时钟

Create a colored clock like here:
创建一个彩色时钟:

[iframe src="solution" height=60]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

When we need to insert a piece of HTML somewhere, `insertAdjacentHTML` is the best fit.
当我们需要在 HTML 某处插入元素,`insertAdjacentHTML` 是最好方案。

The solution:
具体做法:

```js
one.insertAdjacentHTML('afterend', '<li>2</li><li>3</li>');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 5

---

# Insert the HTML in the list
# HTML 标签中插入列表

Write the code to insert `<li>2</li><li>3</li>` between two `<li>` here:
编写需要插入的文本代码 `<li>2</li><li>3</li>`,插入到两个 `<li>` 之中:

```html
<ul id="ul">
Expand Down
14 changes: 7 additions & 7 deletions 2-ui/1-document/07-modifying-document/12-sort-table/solution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The solution is short, yet may look a bit tricky, so here I provide it with extensive comments:
这个方法很精简,但是看起来有点难理解,所以我添加了一些注释:


```js
Expand All @@ -9,11 +9,11 @@ let sortedRows = Array.from(table.rows)
table.tBodies[0].append(...sortedRows);
```

1. Get all `<tr>`, like `table.querySelectorAll('tr')`, then make an array from them, cause we need array methods.
2. The first TR (`table.rows[0]`) is actually a table header, so we take the rest by `.slice(1)`.
3. Then sort them comparing by the content of the first `<td>` (the name field).
4. Now insert nodes in the right order by `.append(...sortedRows)`.
1. 使用 `table.querySelectorAll('tr')` 获取所有 `<tr>`,然后生成数组,因为我们需要用到数组方法。
2. 第一个 TR(`table.rows[0]`)实际上是 table 头,所以我们需要调用 `.slice(1)` 裁剪掉。
3. 比较 `<td>` 的内容(字符在字符集中的序号),进行排序。
4. 现在使用 `.append(...sortedRows)` 插入节点。

Tables always have an implicit <tbody> element, so we need to take it and insert into it: a simple `table.append(...)` would fail.
table 永远包含 <tbody> 元素,所以我们需要考虑到它,并将内容插入到其中:单纯的调用 `table.append(...)` 将会失败。

Please note: we don't have to remove them, just "re-insert", they leave the old place automatically.
请留意:我们没有移除操作,只进行“重复插入”,它们会将旧的位置的内容自动去除。
4 changes: 2 additions & 2 deletions 2-ui/1-document/07-modifying-document/12-sort-table/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ There's a table:
</tr>
</table>

There may be more rows in it.
可能会有更多的行数。

Write the code to sort it by the `"name"` column.
编写代码对 `"name"` 列进行排序。
10 changes: 5 additions & 5 deletions 2-ui/1-document/07-modifying-document/4-clear-elem/solution.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

First, let's see how *not* to do it:
首先我们看看**错误**的做法:

```js
function clear(elem) {
Expand All @@ -9,11 +9,11 @@ function clear(elem) {
}
```

That won't work, because the call to `remove()` shifts the collection `elem.childNodes`, so elements start from the index `0` every time. But `i` increases, and some elements will be skipped.
这是无效的,因为调用 `remove()` 从前面开始移除 `elem.childNodes` 集合里元素,元素的起始下标一直都是 `0`,但是 `i` 却一直在增长,有的元素会直接被忽略了。

The `for..of` loop also does the same.
`for..of` 循环的结果也跟上面一样。

The right variant could be:
正确的做法是:

```js
function clear(elem) {
Expand All @@ -23,7 +23,7 @@ function clear(elem) {
}
```

And also there's a simpler way to do the same:
这里还有一种更简便的方法,也能达到我们需要的效果:

```js
function clear(elem) {
Expand Down
8 changes: 4 additions & 4 deletions 2-ui/1-document/07-modifying-document/4-clear-elem/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 5

---

# Clear the element
# 清除元素

Create a function `clear(elem)` that removes everything from the element.
创建一个函数 `clear(elem)` 用来移除元素里的内容。

```html run height=60
<ol id="elem">
Expand All @@ -13,8 +13,8 @@ Create a function `clear(elem)` that removes everything from the element.
</ol>

<script>
function clear(elem) { /* your code */ }
function clear(elem) { /* 你的代码 */ }

clear(elem); // clears the list
clear(elem); // 清除列表
</script>
```
10 changes: 5 additions & 5 deletions 2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
The HTML in the task is incorrect. That's the reason of the odd thing.
HTML 在这个任务中是错误的,这也是造成怪异的原因所在。

The browser has to fix it automatically. But there may be no text inside the `<table>`: according to the spec only table-specific tags are allowed. So the browser adds `"aaa"` *before* the `<table>`.
浏览器会自动修复它。但 `<table>` 可能会没有文本:根据 table 的特殊规范,这是允许的。所以浏览器会在 `<table>` **前面**添加 `"aaa"`。

Now it's obvious that when we remove the table, it remains.
现在当我们移除 table 时,它就被保留下来了。

The question can be easily answered by exploring the DOM using the browser tools. It shows `"aaa"` before the `<table>`.
通过浏览器开发者工具很容易就能在 DOM 找到答案。它显示出 `"aaa"` `<table>` 前面。

The HTML standard specifies in detail how to process bad HTML, and such behavior of the browser is correct.
HTML 标准规范详细描述了对于异常的 HTML 会如何处理,以及浏览器的行为是否合乎规范。
8 changes: 4 additions & 4 deletions 2-ui/1-document/07-modifying-document/5-why-aaa/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 1

---

# Why does "aaa" remain?
# 为什么留下 "aaa"

Run the example. Why does `table.remove()` not delete the text `"aaa"`?
运行下面例子,为什么 `table.remove()` 没有删除 `"aaa"` 文本?

```html height=100 run
<table id="table">
Expand All @@ -15,9 +15,9 @@ Run the example. Why does `table.remove()` not delete the text `"aaa"`?
</table>

<script>
alert(table); // the table, as it should be
alert(table); // table 应该显示出的样子

table.remove();
// why there's still aaa in the document?
// 为什么 aaa 依旧在文档中
</script>
```
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Please note the usage of `textContent` to assign the `<li>` content.
请留意 `textContent` 复制 `<li>` 内容的用法。
16 changes: 8 additions & 8 deletions 2-ui/1-document/07-modifying-document/6-create-list/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ importance: 4

---

# Create a list
# 创建一个列表

Write an interface to create a list from user input.
编写一个接口,根据用户输入生成一个列表。

For every list item:
每一个列表项:

1. Ask a user about its content using `prompt`.
2. Create the `<li>` with it and add it to `<ul>`.
3. Continue until the user cancels the input (by pressing `key:Esc` or CANCEL in prompt).
1. 使用 `prompt` 询问用户输入的内容。
2. 创建 `<li>` 并添加到 `<ul>`
3. 重复以上两步,直到用户输入取消指令(按下 `key:Esc` 或者 prompt 的 CANCEL)。

All elements should be created dynamically.
所有元素应该都是动态创建的。

If a user types HTML-tags, they should be treated like a text.
如果把用户输入了 HTML 标签,就应该将其视为文本。

[demo src="solution"]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The easiest way to walk the object is to use recursion.
在对象间游走的最简单方式就是递归了。

1. [The solution with innerHTML](sandbox:innerhtml).
2. [The solution with DOM](sandbox:build-tree-dom).
22 changes: 11 additions & 11 deletions 2-ui/1-document/07-modifying-document/7-create-object-tree/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Create a tree from the object
# 利用对象创建节点树

Write a function `createTree` that creates a nested `ul/li` list from the nested object.
编写一个函数 `createTree` 将嵌套的对象生成 `ul/li` 的嵌套列表。

For instance:
例如:

```js
let data = {
Expand All @@ -28,24 +28,24 @@ let data = {
};
```

The syntax:
语句:

```js
let container = document.getElementById('container');
*!*
createTree(container, data); // creates the tree in the container
createTree(container, data); // container 中创建树。
*/!*
```

The result (tree) should look like this:
结果(树)看起来像这样:

[iframe border=1 src="build-tree-dom"]

Choose one of two ways of solving this task:
选择其中一种方式来完成这个任务:

1. Create the HTML for the tree and then assign to `container.innerHTML`.
2. Create tree nodes and append with DOM methods.
1. 通过树创建 HTML 然后派发给 `container.innerHTML`
2. 创建节点树然后插入到 DOM 中。

Would be great if you could do both.
如果两种方式都尝试一下就更好。

P.S. The tree should not have "extra" elements like empty `<ul></ul>` for the leaves.
P.S. 树应该没有“额外”的元素,像空的 `<ul></ul>` 没有列表项。
Original file line number Diff line number Diff line change
@@ -1 +1 @@
To append text to each `<li>` we can alter the text node `data`.
为每个 `<li>` 插入文本,我们可以改变文本节点 `data`
8 changes: 4 additions & 4 deletions 2-ui/1-document/07-modifying-document/8-tree-count/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ importance: 5

---

# Show descendants in a tree
# 在树中显示后代

There's a tree organized as nested `ul/li`.
这里有一棵由嵌套的 `ul/li` 组成的树。

Write the code that adds to each `<li>` the number of its descendants. Skip leaves (nodes without children).
编写代码在 `<li>` 添加后代数量的数字。跳过一些叶子(如果节点没有后代节点)。

The result:
最终结果:

[iframe border=1 src="solution"]
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
We'll create the table as a string: `"<table>...</table>"`, and then assign it to `innerHTML`.
我们用字符串创建 table`"<table>...</table>"`,然后派发给 `innerHTML`

The algorithm:
算法如下:

1. Create the table header with `<th>` and weekday names.
1. Create the date object `d = new Date(year, month-1)`. That's the first day of `month` (taking into account that months in JavaScript start from `0`, not `1`).
2. First few cells till the first day of the month `d.getDay()` may be empty. Let's fill them in with `<td></td>`.
3. Increase the day in `d`: `d.setDate(d.getDate()+1)`. If `d.getMonth()` is not yet the next month, then add the new cell `<td>` to the calendar. If that's a Sunday, then add a newline <code>"&lt;/tr&gt;&lt;tr&gt;"</code>.
4. If the month has finished, but the table row is not yet full, add empty `<td>` into it, to make it square.
1. 通过 `<th>` 创建 table 头和周末名字。
1. 创建一个日期对象 `d = new Date(year, month-1)`。它是`月份`的第一天(注意 JavaScript 计算月份是从 `0` 开始,而不是 `1`)。
2. 将每月第一天的日期生成单元格,直到月份的第一天 `d.getDay()` 是空的。然后将它们填充到 `<td></td>`
3. 天数增长 `d``d.setDate(d.getDate()+1)`。如果 `d.getMonth()` 不是下一个月,就添加新单元格 `<td>` 到日历表中,如果那天是星期日,就添加一行 <code>"&lt;/tr&gt;&lt;tr&gt;"</code>
4. 如果天数遍历完但 table 没有填满,就用空的 `<td>` 补齐。
12 changes: 6 additions & 6 deletions 2-ui/1-document/07-modifying-document/9-calendar-table/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ importance: 4

---

# Create a calendar
# 创建一个日历

Write a function `createCalendar(elem, year, month)`.
编写一个函数 `createCalendar(elem, year, month)`

The call should create a calendar for the given year/month and put it inside `elem`.
调用后会创建一个日历并添加到 `elem`

The calendar should be a table, where a week is `<tr>`, and a day is `<td>`. The table top should be `<th>` with weekday names: the first day should be Monday, and so on till Sunday.
日历应该是一个 table,每一周用 `<tr>` 表示,每一天用 `<td>` 表示。table 顶部是 `<th>` 表示周几:第一天应该是星期一,直到星期日。

For instance, `createCalendar(cal, 2012, 9)` should generate in element `cal` the following calendar:
例如,`createCalendar(cal, 2012, 9)` 应该在 `cal` 生成一个日历,如下:

[iframe height=210 src="solution"]

P.S. For this task it's enough to generate the calendar, should not yet be clickable.
P.S. 这里只要生成一个展示日历就好,不需要点击交互功能。
Loading