> For the complete documentation index, see [llms.txt](https://owen31302.gitbook.io/github-education/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://owen31302.gitbook.io/github-education/become-a-front-end-web-developer-or-udacity-3.-javascript-and-the-dom/3.-javascript-and-the-dom/lesson-2-the-document-object-model.md).

# Lesson 2: The Document Object Model

## Update Existing Page Content <a href="#header-title" id="header-title"></a>

### 1. Update an Element's Inner HTML <a href="#an-element-s-inner-html" id="an-element-s-inner-html"></a>

顯示某個element底下的html

The `.innerHTML` property sets or returns the HTML content *inside* the selected element (i.e. between the tags).

```javascript
document.querySelector('.card').innerHTML
```

There's also the rarely used `.outerHTML` property. `.outerHTML` represents the HTML element itself, *as well as its children*.

```javascript
<h1 id="pick-me">Greetings To <span>All</span>!</h1>

const innerResults = document.querySelector('#pick-me').innerHTML;
console.log(innerResults); // logs the string: "Greetings To <span>All</span>!"

const outerResults = document.querySelector('#pick-me').outerHTML;
console.log(outerResults); // logs the string: "<h1 id="pick-me">Greetings To <span>All</span>!</h1>"
```

更新innerHTML

```javascript
myElement.innerHTML = 'The <strong>Greatest</strong> Ice Cream Flavors';
```

### 2. Update an Element's Text Content <a href="#an-element-s-text-content" id="an-element-s-text-content"></a>

So `.innerHTML` will get/set an element's *HTML* content. If we just want the text content, we can use the fantastically named `.textContent` property!

The `.textContent` property will:

* set the text content of an element and all its descendants
* return the text content of an element and all its descendants

![](/files/-M6YRo57UIlaFZ4_1CJG)

Check out the `.textContent`'s documentation page on MDN: [textContent docs](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)

更新內容：

```javascript
nanodegreeCard.textContent = "I will be the updated text for the nanodegreeCard element!";
```

{% hint style="warning" %}
textContent會把內容當作plain text輸出，而innerHTML則會parse內文的html tag。
{% endhint %}

### 3. An Element's Text Content - Version 2! <a href="#an-element-s-text-content-version-2" id="an-element-s-text-content-version-2"></a>

`.innerText` will get the ***visible*** text of the element. If CSS is used to hide any text inside that element, `.innerText` ***will not*****&#x20;return that text**, while `.textContent` *will* return it.

innerText顯示apply css之後的文字，而textContent則回傳apply css之前的文字。

## Add New Page Content <a href="#header-title" id="header-title"></a>

之前為修改現有element，現在為新增element。

### 1. Adding Content To The Page <a href="#adding-content-to-the-page" id="adding-content-to-the-page"></a>

As you've already discovered, the `.createElement()` method is a method on the `document` object:

<https://developer.mozilla.org/en-US/docs/Web/API/Document>

<https://developer.mozilla.org/en-US/docs/Web/API/Node>

<https://developer.mozilla.org/en-US/docs/Web/API/Element>

```javascript
// creates and returns a <span> element
document.createElement('span');

// creates and returns an <h3> element
document.createElement('h3');
```

createElement只是建立新增的element，針對想要新增的element target呼叫appendChild才會新增element上去：

```javascript
// create a brand new <span> element
const newSpan = document.createElement('span');

// select the first (main) heading of the page
const mainHeading = document.querySelector('h1');

// add the <span> element as the last child element of the main heading
mainHeading.appendChild(newSpan);
```

![](/files/-M6_i9pCjFOwYdmyLKc6)

{% hint style="warning" %}
**.appendChild()** Needs An Element!
{% endhint %}

This is stated above, but I wanted to call this out, specifically. When you're using the `.appendChild()` method, it must be called on an existing element. To be clear, you can't call this on the `document` object, so the following will result in an error:

```javascript
const newSpan = document.createElement('span');

// causes an error
document.appendChild(newSpan);
```

### 2. Creating Text Nodes <a href="#creating-text-nodes" id="creating-text-nodes"></a>

第二種方式則是產生內文後，再添加到element，多一個步驟：

* creates a paragraph element
* creates a text node
* appends the text node to the paragraph
* appends the paragraph to the tag

```javascript
const myPara = document.createElement('p');
const textOfParagraph = document.createTextNode('I am the text for the paragraph!');

myPara.appendChild(textOfParagraph);
document.body.appendChild(myPara);
```

![](/files/-M6bjAonDdVx0q_FJcmu)

用以下的方式產生一樣的結果：

```javascript
const myPara = document.createElement('p');

myPara.textContent = 'I am the text for the paragraph!';
document.body.appendChild(myPara);
```

{% hint style="warning" %}
如果將同一個element多次appendChild給不同element，則只會append到最後一個指定的element。
{% endhint %}

### 3. Inserting HTML In Other Locations <a href="#inserting-html-in-other-locations" id="inserting-html-in-other-locations"></a>

問題：appendChild只能插入parent的child的最後一個位置。

解法：.insertAdjacentHTML()

Enter the `.insertAdjacentHTML()` method! The `.insertAdjacentHTML()` method has to be called with two arguments:

* the location of the HTML
* the HTML text that is going to be inserted

The first argument to this method will let us insert the new HTML in one of four different locations

* `beforebegin` – inserts the HTML text as a previous sibling
* `afterbegin` – inserts the HTML text as the first child
* `beforeend` – inserts the HTML text as the last child
* `afterend` – inserts the HTML text as a following sibling

```javascript
<!-- beforebegin -->
<p>
    <!-- afterbegin -->
    Existing text/HTML content
    <!-- beforeend -->
</p>
<!-- afterend -->
```
