<style>
html, body, .ui-content {
background-color: #333;
color: #ddd;
}
.navbar-default {
background-color: #ffffff98;
backdrop-filter: blur(20px);
border-color: transparent;
}
body > .ui-infobar {
display: none;
}
.community-button {
color: #ddd;
transition: all .2s ease;
}
.community-button:hover {
color: #333;
}
.dropdown-menu {
font-size: 14px;
background-color: #222;
border-radius: 10px;
}
.ui-infobar {
color: #ddd;
}
.ui-view-area > .ui-infobar {
display: block;
}
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
color: #ddd;
}
.markdown-body h1 {
background: linear-gradient(70deg,#FBF4EC 10%,#ECD7C8 23.3%,#EEA4BC 36.6%,#BE88C4 49.9%,#9186E7 63.2%,#92C9F9 76.5%,#C7F8FF 90%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: all 0.5s ease;
}
.markdown-body h2 {
background: linear-gradient(90deg,#ff9fe1 0%,#8727ff 90%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: all 0.5s ease;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom-color: #ffffff69;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #fff;
}
.markdown-body img {
background-color: transparent;
}
.ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a {
color: white;
border-left: 2px solid white;
}
.expand-toggle:hover,
.expand-toggle:focus,
.back-to-top:hover,
.back-to-top:focus,
.go-to-bottom:hover,
.go-to-bottom:focus {
color: white;
}
.ui-toc-dropdown {
background-color: #222;
border-radius: 10px;
padding: 10px;
}
.ui-toc-label.btn {
background-color: #191919;
color: white;
}
.ui-toc-dropdown .nav>li>a:focus,
.ui-toc-dropdown .nav>li>a:hover {
color: white;
border-left: 1px solid white;
}
.markdown-body blockquote {
color: #bcbcbc;
}
.markdown-body table tr {
background-color: #5f5f5f;
}
.markdown-body table tr:nth-child(2n) {
background-color: #4f4f4f;
}
.markdown-body code,
.markdown-body tt {
color: #eee;
background-color: rgba(230, 230, 230, 0.36);
}
.markdown-body pre {
background-color: #eee;
}
.token.keyword {
/* color: #fff; */
}
.alert-warning {
/* background-color: #000000; */
}
a,
.open-files-container li.selected a {
color: #5EB7E0;
}
</style>
# JavaScript 基礎與 HTML DOM 操作
**本次課程你將學到:**
* JavaScript 基本語法
* 知道什麼是 DOM
* HTML DOM 常用的屬性及方法
---
## JavaScript 是什麼?
JavaScript (又稱 JS ) 是一種腳本語言,也是一種程式語言。它可以在靜態的網頁上增加功能,例如:即時更新網頁內容、影音播放、控制多媒體動畫、點擊按鈕觸發某些事件等等,讓使用者能與網頁進行互動。
:::info
簡單來說就是,JavaScript 賦予網頁動態的生命力。
:::

JS 與 HTML、CSS 搭配使用,就可以做出各式各樣的網頁囉!
## 如何撰寫 JavaScript ?
==**本課程以 VS Code 為主要編輯工具**==
1. 開啟 VS Code
2. 點擊左側「延伸模組 (Extenstions) 」

3. 搜尋 code runner 並安裝

4. 點擊「新增檔案 (New File)」,並輸入檔案名稱,記得最後面要加上.js

5. 點擊右上角的 Run Code (三角形圖案) 即可執行程式

---
## 基本語法概述
### 資料型態
* Number:包含所有的正數、負數、小數。
> 例如:57、-200、3.14159
* String:純文字,要使用雙引號 `"` 或單引號 `'` 。
> 例如:"中央大學"、'I Love JS!!!!'
* Object:可以想像成一個清單、列表,每一項用逗號分開。
Object 可再細分為兩種:
1. 使用中括號 `[]`,是有順序性的,編號從 0 開始依序由左至右。
> 例如:["王小明", 1110508, 3]
2. 使用大括號 `{}`,沒有順序性,也沒有編號,取而代之的是冒號左邊的內容。
> 例如:{姓名: "王小明", 學號: 1110508, 年齡: 3}
* Boolean:`true` 或 `false`。
* Undefined:當宣告變數時沒有賦予一個值時,他的型態即為 Undefined。
### 輸出
JS 的輸出會顯示在 Console (控制台)
:::info
如果在 VS Code 執行:
會直接顯示在畫面下方
如果在 Chrome 執行:
要打開開發者工具 (DevTools) 才看得到,可以按鍵盤的 F12 把它打開。
:::
**語法:`console.log(要顯示的內容);`**
例如:
```javascript=
console.log(3);
console.log(2 + 5);
console.log("This is a book.");
console.log(["王小明", 1110508, 3]);
console.log({"姓名": "王小明", "學號": 1110508, "年齡": 3});
```
:::info
**補充 `typeof()` :**
把東西放進括號裡,它會告訴我們括號裡的內容是什麼資料型態。
例如:
```javascript=
console.log(typeof(3)); // 輸出 number
console.log(typeof("今天天氣真好")); // 輸出 string
```
:::
### 宣告變數
變數是個可以用來儲存資料的容器,宣告方式有三種:
* `const`:在宣告時,一定要賦予一個值,宣告以後,再也不能修改。
```javascript
const x = 9;
const y = "Good Morning";
```
* `let`:隨時都可以修改,一開始不一定要賦予值
```javascript
let a = 9;
let b;
```
* `var`:與 `let` 幾乎相同,但不建議使用,有興趣可以閱讀以下文章。
:link: [JavaScript: var, let, const 差異](https://totoroliu.medium.com/javascript-var-let-const-%E5%B7%AE%E7%95%B0-e3d930521230)
:::info
**為了程式的易讀性,盡量避免使用沒有意義的命名方式。**
以下是建議的命名方式:
**<span style="color: #EB5357">駝峰式命名法</span>** (Camel case) 是常用的變數命名方式之一,規則為:
由多個有意義的單字組成,第一個字母小寫,之後的每個單字的首字母大寫。
例如:
```javascript=
const myName = "Steven Paul Jobs";
let userInputText;
```
:::
<!-- ### 條件敘述
**語法:**
```javascript
if (條件一) {
...
}
else if (條件二) {
...
}
else if (條件三) {
...
}
else {
...
}
``` -->
### 函式
當有一些功能需要重複使用時,用函式的寫法能夠大幅減少程式碼,除了方便撰寫、閱讀之外,當程式越來越龐大時,在維護上也能更加容易、輕鬆。
數學中的函式大概長這樣:$f(x)=x^2+2x-3$
JavaScript 中的函式長得跟它很像:
```javascript=
function f(x) {
return x*x + 2*x - 3;
}
```
以上面的程式碼為例:
:::warning
* `f` 為函式的名稱
* 括號裡的 `x` 是參數,可有可無
* `return` 是回傳的意思
* `return` 後面是要回傳的東西
:::
要使用函式時,只要打上函數名稱加一組括號 `()` 即可,如果有參數,將參數放入括號內。
假如我想使用上面的 f 函式,並把 x = 3 代入:
```javascript
f(3);
```
將它輸出:
```javascript=4
console.log(f(3)); // 18
```
[**👉 點我看範例 👈**](https://codepen.io/xumyk_code/pen/popZVex?editors=0010)
:::info
JavaScript 表示函式的方法有很多種,上面所介紹的是最直覺的方式。其他的表示法會在操作 DOM 時介紹給大家。
:::
---
## 認識文件物件模型 DOM
DOM 的英文全名是 **D**ocument **O**bject **M**odel,中文是「文件物件模型」。
> 是 HTML、XML 和 SVG 文件的程式介面。它提供了一個文件(樹)的結構化表示法,並定義讓程式可以存取並改變文件架構、風格和內容的方法。DOM 提供了文件以擁有屬性與函式的節點與物件組成的結構化表示。節點也可以附加事件處理程序,一旦觸發事件就會執行處理程序。 本質上,它將網頁與腳本或程式語言連結在一起。<br/>
[:link: 參考來源](https://developer.mozilla.org/zh-TW/docs/Web/API/Document_Object_Model)
簡單來說,DOM 是一個將 HTML 文件以樹狀結構來表示的模型,我們稱之為「 DOM Tree 」。
例如,把以下的 HTML 轉換成 DOM Tree:

會變成這樣:

以 Document 為起點,可以延伸出許多的 HTML 標籤 ( Element ),一個節點就是一個標籤,往下又可以再延伸出「Attribute 節點」與「Text 節點」。
單純的 HTML 網頁是靜態的,顯示的內容是固定的,不能更改,但有了這個模型,我們就可以透過 JavaScript 來取得、新增、修改、刪除 HTML 元素,實現動態 HTML。
## 開始使用 HTML DOM
==要先準備好一個 html 檔==
**step1.** 建立一個 JavaScript 檔案 (.js)
**step2.** 在 `<body>` 的最底下加上一行程式碼,把 js 嵌入 html:
```htmlembedded=
<script src="./fileName.js"></script>
```
:bulb: `src` 內寫的是檔案路徑 `./` 代表 js 檔跟 html 檔在同一個資料夾裡
### 取得 HTML 元素
這裡需要用到 document 的 **方法 (method)**
:::info
**方法 (Method) 與 屬性 (Property):**
* 方法:可以理解成函數。
* 屬性:這個跟 HTML 的屬性 (Attribute)
雖然中文相同,但是是不一樣的東西,要注意。
要以外觀來區別方法跟屬性,最容易的方式就是看有沒有括號 `()`
:::
有很多方法 (Method) 可以拿到 HTML 的元素
1. 用標籤名稱取得,會得到所有符合條件的元素
```javascript=
document.getElementsByTagName("標籤名稱");
```
2. 用 `id` 取得,會得到第一個符合條件的元素
```javascript=
document.getElementById("元素的id");
```
3. 用 `class` 取得,會得到所有符合條件的元素
```javascript=
document.getElementsByClassName("元素的class");
```
4. 用 `id` 或 `class` 都可以(需要註明,與 CSS 寫法相同)。會得到第一個符合條件的元素
```javascript=
document.querySelector(".className");
document.querySelector("#idName");
```
5. 用 `id` 或 `class` 都可以(需要註明,與 CSS 寫法相同),可以有多個條件。會得到所有符合條件的元素
如果有多個條件,則每個條件要以逗號 `,` 分開
```javascript=
document.querySelectorAll(".className");
document.querySelectorAll(".className, #idName");
```
而選取出來的元素,我們可以使用 `textContent` 屬性來變更它的文字。
### 更改 HTML 元素內容
定義一個 HTML 屬性為 `id`,名稱為 header:
```htmlembedded=
<h1 id="header"></h1>
```
可以透過 `document.getElementById()` 方法來取得該元素,然後使用 `textContent` 屬性修改文字內容:
```javascript=
document.getElementById('header').textContent = "Welcome to NCU!"
```
[**👉 點我看範例 👈**](https://codepen.io/xumyk_code/pen/xxpjomx)
現在我們學會如何取得元素以及修改元素的內容了,但這樣還是不夠動態,我們希望網頁可以有按鈕,並且能透過按鈕改變網頁的內容。
### 事件監聽 addEventListener()
語法:
```javascript
addEventListener('事件名稱', 要做的事)
```
「事件」包含滑鼠點擊、拖曳、鍵盤輸入等等,也就是使用者的各種操作,其中,最常見的是按按鈕,按按鈕就是屬於一個滑鼠點擊的事件。
我們可以透過 document 的方法取得元素,並偵測使用者有沒有對這個元素做什麼動作,進而做出回應。
例如:
```htmlembedded=
<!-- html -->
<p id="text">這是原本的文字</p>
<button id="changeTextBtn">改變文字</button>
```
我希望可以按按鈕來改變文字內容,我們可以這樣做:
**step1.** 先取得文字和按鈕兩個元素
```javascript=
// javascript
const text = document.getElementById("text");
const button = document.getElementById("changeTextBtn");
```
**step2.** 接下來要偵測按鈕有沒有被點擊,「點擊」這個事件叫做 `"click"`,如果按鈕被點,我就要改變 `<p>` 內的文字:
```javascript=4
button.addEventListener("click", () => {
text.textContent = "我變成其他文字了!!"
});
```
[**👉 點我看範例 👈**](https://codepen.io/xumyk_code/pen/jOaJGPo?editors=1010)
這邊看起來有點複雜,我們一步一步分析。
`() => {}` :這是 JavaScript 編寫函式的一種比較特別的方式,跟我們平常看到的長不太一樣,但它其實很容易理解。
這種寫法稱作 **<span style="color: #EB5357">箭頭函式</span>** ,顧名思義,它多了一個箭頭 `=>` 。
:::info
`()` 跟一般定義函式的括號一樣意思,裡面可以放參數,也可以什麼都不放。
`{}` 也跟一般的函式一樣意思,裡面放的是要執行的內容。
:::
再回頭看看這一段程式,應該變得淺顯易懂了吧,這樣子就可以讓你的網頁動起來了!
---
**[下一篇:Bootstrap 教學](https://hackmd.io/8DfCfwg8TeCrH9TA0ge4tQ?view)**