diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md index 5cc3217961..81848b2134 100644 --- a/2-ui/1-document/07-modifying-document/article.md +++ b/2-ui/1-document/07-modifying-document/article.md @@ -1,16 +1,14 @@ -# 修改文档内容 +# 修改文档(document) -DOM(document object model 文档对象模型,此文中全部以缩写 DOM 表示)的可修改性是网页能“实时”刷新的关键。 +DOM 修改是创建“实时”页面的关键。 -以下的例子向我们展示如何创建一个“弹幕”新元素并且修改它在页面中展示的内容。 +在这里,我们将会看到如何“即时”创建新元素并修改现有页面内容。 -这里我们先展示出一个简单的例子,随后会逐一向你说明。 +## 例子:展示一条消息 -## 例子:展示一条信息 +让我们使用一个示例进行演示。我们将在页面上添加一条比 `alert` 更好看的消息。 -首先,我们可以看到一条信息,它看起来像是一个美化版的 `alert`。 - -这里是它的样式: +它的外观如下: ```html autorun height="80" ``` +## 节点移除 + +想要移除一个节点,可以使用 `node.remove()`。 + +让我们的消息在一秒后消失: + +```html run untrusted + + + +``` + +请注意:如果我们要将一个元素 **移动** 到另一个地方,则无需将其从原来的位置中删除。 + +**所有插入方法都会自动从旧位置删除该节点。** + +例如,让我们进行元素交换: + +```html run height=50 +
First
+
Second
+ +``` + ## 克隆节点:cloneNode -怎么插入多条相同的信息? +如何再插入一条类似的消息? -我们可以声明一个函数来实现这个方法。但是怎样通过**克隆**的方式来替换掉那些原本存在的 `div` 并且更改里面的文本(如果有这样一个需求)。 +我们可以创建一个函数,并将代码放在其中。但是另一种方法是 **克隆** 现有的 `div`,并修改其中的文本(如果需要)。 -如果我们有一个很大的元素,克隆的方式要远比创建后插入来的更简单,性能也更好。 +当我们有一个很大的元素时,克隆的方式可能更快更简单。 -- `elem.cloneNode(true)` 方法用来对一个元素进行“深”克隆 —— 包括所有特性和子元素。`elem.cloneNode(false)` 方法只克隆该元素本身,不对子元素进行克隆。 +调用 `elem.cloneNode(true)` 来创建元素的一个“深”克隆 — 具有所有特性(attribute)和子元素。如果我们调用 `elem.cloneNode(false)`,那克隆就不包括子元素。 -一个复制信息的例子: +一个拷贝消息的示例: ```html run height="120" + ```html run height=100 +
    +
  1. 0
  2. +
  3. 1
  4. +
  5. 2
  6. +
+ + ``` + 如果要将 `newLi` 插入为第一个元素,我们可以这样做: - document.body.append(div); -*!* - setTimeout(() => div.remove(), 1000); - // or setTimeout(() => document.body.removeChild(div), 1000); -*/!* - -``` + ```js + list.insertBefore(newLi, list.firstChild); + ``` + +`parentElem.replaceChild(node, oldChild)` +: 将 `parentElem` 的后代中的 `oldChild` 替换为 `node`。 + +`parentElem.removeChild(node)` +: 从 `parentElem` 中删除 `node`(假设 `node` 为 `parentElem` 的后代)。 + + 下面这个示例从 `
    ` 中删除了 `
  1. `: + + ```html run height=100 +
      +
    1. 0
    2. +
    3. 1
    4. +
    5. 2
    6. +
    + + + ``` + +所有这些方法都会返回插入/删除的节点。换句话说,`parentElem.appendChild(node)` 返回 `node`。但是通常我们不会使用返沪值,我们只是使用对应的方法。 ## 聊一聊 "document.write" -`document.write` 是一个很老的方法,用来为 web 页面添加内容。 +还有一个非常古老的向网页添加内容的方法:`document.write`。 语法如下: @@ -477,15 +476,15 @@ ul.append(...getListContent()); // append + “...” 操作符 = 一对好朋

    The end

    ``` -调动 `document.write(html)` 时意味着将 `html` “就地并马上”放入到页面中。`html` 字符串会动态的创建,所以它以自动伸缩的方式放入到页面中。我们可以通过 JavaScript 创建一个完整的 HTML 页面并写入浏览器窗口中。 +调用 `document.write(html)` 意味着将 `html` “就地马上”写入页面。`html` 字符串可以是动态生成的,所以它很灵活。我们可以使用 JavaScript 创建一个完整的页面并对其进行写入。 -这个方法的起源于没有 DOM,没有 Web 标准的上古时期……,但是这个方法依旧保留了下来,因为很多的脚本使用它来实现一些功能。 +这个方法来自于没有 DOM,没有标准的上古时期……。但这个方法依被保留了下来,因为还有脚本在使用它。 -现代的脚本已经很少再看到这个方法,因为使用它有一个很重要的局限性: +由于以下重要的限制,在现代脚本中我们很少看到它: -**只能在页面加载的时候调用 `document.write`。** +**`document.write` 调用只在页面加载时工作。** -如果在加载完成以后,渲染好的页面会被擦除。 +如果我们稍后调用它,则现有文档内容将被擦除。 例如: @@ -493,61 +492,57 @@ ul.append(...getListContent()); // append + “...” 操作符 = 一对好朋

    After one second the contents of this page will be replaced...

    *!* */!* ``` -所以,不像其他 DOM 操作一样,一旦页面“加载完毕”最好就不使用 document.write 方法。 +因此,在某种程度上讲,它在“加载完成”阶段是不可用的,这与我们上面介绍的其他 DOM 方法不同。 这是它的缺陷。 -从技术上讲,当浏览器正在读取(“解析”)传入的 HTML ,此时再调用 `document.write` 方法向文档中写入一些东西,浏览器会像它本来就在整个 HTML 文本的那个位置上(调用 document.write 的地方)一样处理它。 -“ it were initially there” +还有一个好处。从技术上讲,当在浏览器正在读取(“解析”)传入的 HTML 时调用 `document.write` 方法来写入一些东西,浏览器会像它本来就在 HTML 文本中那样使用它。 -反过来说这也是一个优势 —— 它性能出奇的快,因为它不用**修改 DOM 结构**。它直接在 DOM 结构构建之前,对整个页面直接进行重写,再交给浏览器去构建 DOM 结构。 +所以它运行起来出奇的快,因为它 **不涉及 DOM 修改**。它直接写入到页面文本中,而此时 DOM 尚未构建。 -所以如果我们需要在 HTML 加载阶段动态的添加很多文本,它会很高效。不过能用到的机会不多就是了。在一些很老的脚本里倒是能经常看到。 +因此,如果我们需要向 HTML 动态地添加大量文本,并且我们正处于页面加载阶段,并且速度很重要,那么它可能会有帮助。但实际上,这些要求很少同时出现。我们可以在脚本中看到此方法,通常是因为这些脚本很旧。 ## 总结 -创建节点的方法: - -- `document.createElement(tag)` —— 用给定标签创建一个节点, -- `document.createTextNode(value)` —— 创建一个文本节点(很少使用), -- `elem.cloneNode(deep)` —— 如果参数 `deep==true` 将元素及后代子元素进行克隆。 - -插入和移除节点的方法: +- 创建新节点的方法: + - `document.createElement(tag)` — 用给定的标签创建一个元素节点, + - `document.createTextNode(value)` — 创建一个文本节点(很少使用), + - `elem.cloneNode(deep)` — 克隆元素,如果 `deep==true` 则与其后代一起克隆。 -- 从 parent - - `parent.appendChild(node)` - - `parent.insertBefore(node, nextSibling)` - - `parent.removeChild(node)` - - `parent.replaceChild(newElem, node)` +- 插入和移除节点的方法: + - `node.append(...nodes or strings)` — 在 `node` 末尾插入, + - `node.prepend(...nodes or strings)` — 在 `node` 开头插入, + - `node.before(...nodes or strings)` — 在 `node` 之前插入, + - `node.after(...nodes or strings)` — 在 `node` 之后插入, + - `node.replaceWith(...nodes or strings)` — 替换 `node`。 + - `node.remove()` — 移除 `node`。 - 这些方法都返回 `node`。 + 文本字符串被“作为文本”插入。 -- 添加一些节点和字符串: - - `node.append(...nodes or strings)` —— 在 `node` 末尾位置增加, - - `node.prepend(...nodes or strings)` —— 在 `node`开头位置增加 , - - `node.before(...nodes or strings)` —— 在 `node` 之前位置增加, - - `node.after(...nodes or strings)` —— 在 `node` 之后位置增加, - - `node.replaceWith(...nodes or strings)` —— 替换 `node`。 - - `node.remove()` —— 移除 `node`。 +- 这里还有“旧式”的方法: + - `parent.appendChild(node)` + - `parent.insertBefore(node, nextSibling)` + - `parent.removeChild(node)` + - `parent.replaceChild(newElem, node)` - 把字符串当成“文本”插入。 + 这些方法都返回 `node`。 -- 在 HTML 中添加内容 `elem.insertAdjacentHTML(where, html)`,在 where 位置进行操作: - - `"beforebegin"` —— 将 `html` 插入 `elem` 到开头的前面位置, - - `"afterbegin"` —— 将 `html` 插入 `elem` 到开头的后面位置, - - `"beforeend"` —— 将 `html` 插入 `elem` 到结尾的前面位置, - - `"afterend"` —— 将 `html` 插入 `elem` 到结尾的后面位置。 +- 在 `html` 中给定一些 HTML,`elem.insertAdjacentHTML(where, html)` 会根据 `where` 的值来插入它: + - `"beforebegin"` — 将 `html` 插入到 `elem` 前面, + - `"afterbegin"` — 将 `html` 插入到 `elem` 的开头, + - `"beforeend"` — 将 `html` 插入到 `elem` 的末尾, + - `"afterend"` — 将 `html` 插入到 `elem` 后面。 - `elem.insertAdjacentText` 和 `elem.insertAdjacentElement` 跟 `elem.insertAdjacentHTML` 很相似,只不过他们一个用来插入字符串,一个用来插入元素,但是很少使用这两个方法。 +另外,还有类似的方法,`elem.insertAdjacentText` 和 `elem.insertAdjacentElement`,它们会插入文本字符串和元素,但很少使用。 -- 在页面加载完成之前添加 HTML 到页面中: - - `document.write(html)` +- 要在页面加载完成之前将 HTML 附加到页面: + - `document.write(html)` - 如果是在页面加载完成以后调用会擦除加载完毕的内容。通常在很老的脚本才会使用这个方法了。 + 页面加载完成后,这样的调用将会擦除文档。多见于旧脚本。