你的第二個 WebExtension - Mozilla

你的第二個 WebExtension
==================

假如你已經讀過了 你的第一個 WebExtension，你也已經知道該如何寫一個 extension（外掛），在這篇文章中我們將會教你寫一個稍微複雜一點的 extension，來 demo 一些 API 的使用。

在這個 extension 中，將會新增一個按鈕到 Firefox 的工具列上，當使用者按下按鈕後，將會顯示一個彈出視窗 (pop-up) 並可選擇一個動物。當使用者選擇了一個動物後，將會在當前的網頁中顯示使用者所選的動物圖片。

為了實作這個，我們將需要：

* **定義一個 browser action (en-US) 給新增於 Firefox 工具列的按鈕。**
 這個按鈕，我們將提供以下功能：
    + 按鈕的 icon，命名為 "beasts-32.png"
    + 當按下按鈕時顯示一個彈出視窗 (pop-up)，這個 pop-up 將會包含 HTML, CSS 和 JavaScript。
* **定義一個 extension 用的 icon，** 命名為 "beasts-48.png". 此 icon 將會顯示於 Add-ons Manager.
* **寫一個內容腳本 "beastify.js" ，該檔案會被當前網頁讀取。**
 讓網頁顯示所選的動物圖片的程式碼會寫在這裡。
* **打包所需要的動物圖片，此圖片是用來顯示按下按鈕後顯示於網頁上的。**
 為了讓網頁可以取用圖片，我們將會讓這些圖片變成可讓 "網頁存取的資源"。

下面是這次 extension 的流程圖：

![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension/untitled-1.png)

這個一個簡單的 extension，但是會教你許多基本的 WebExtensions API 的概念：

* 新增一個按鈕到工具列
* 利用 HTML, CSS 和 JavaScript 去定義一個 pop-up
* 讀取內容腳本到網頁
* 內容腳本與整個 extension 間的溝通
* 打包 extension 所需的資源，讓網頁可以存取

也可以在 GitHub 上找到範例的原始碼： https://github.com/mdn/webextensions-examples/tree/main/beastify

實作這個 extension 前，請先確認你的 Firefox 有 45.0 或更新的版本。

實作 extension
------------

新增一個資料夾，然後進去：

```bash
mkdir beastify
cd beastify
```

### manifest.json

在資料夾 "beastify" 下新增一個檔案，並命名為 "manifest.json"，然後撰寫以下程式碼。

```json
{
  "manifest\_version": 2,
  "name": "Beastify",
  "version": "1.0",

  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
  "homepage\_url": "https://github.com/mdn/webextensions-examples/tree/main/beastify",
  "icons": {
    "48": "icons/beasts-48.png"
  },

  "permissions": ["activeTab"],

  "browser\_action": {
    "default\_icon": "icons/beasts-32.png",
    "default\_title": "Beastify",
    "default\_popup": "popup/choose\_beast.html"
  },

  "web\_accessible\_resources": [
    "beasts/frog.jpg",
    "beasts/turtle.jpg",
    "beasts/snake.jpg"
  ]
}
```

* 最前面的三個 key：`manifest_version`、`name`、`version` 必須寫進去，它包含了附加元件的基本詮釋資料（metadata）。
* `description` (en-US) 和 `homepage_url` 為非必要但建議加上：主要在說明該 extension。
* `icons` (en-US) 為非必要但建議加上：它允許附加元件指定圖示、也會在附加元件的管理員顯示
* `permissions` (en-US) 列出了該 extension 所需要的權限。這邊我們只會要求 `activeTab` permission 。
* `browser_action` (en-US) 定義工具列的按鈕，在這邊我們將會提供三種 key：
    + `default_icon` 為必要的：告訴 button 該使用的 icon 為何
    + `default_title`為非必要的：該 value 會顯示在 button 的 tip 裡
    + `default_popup` 如果想要顯示 pop-up，此為必要的 key：此教學中有使用到 pop-up 故為必要的，並將 HTML 檔案指給他。
* `web_accessible_resources` (en-US) 列出所有希望讓網頁可以存取的檔案。

所有的路徑都會關連到 manifest.json 。

### The icon

一個 extension 應該要有一個 icon。icon 將會顯示在 Add-ons Manager 的 extension 列表中。（在 Firefox 網址列輸入 "about:addons" 開啟 Add-ons Manager）。

在 beastify 下建立一個名為 "icons" 的資料夾，並準備一個命名為 "beasts-48.png" 的 icon 並存在 "beastify/icons" 的資料夾中（可以使用我們的範例圖檔，圖檔來源：Aha-Soft's Free Retina iconset，遵照使用條款來使用）。並在 manifest.json 裡告訴他要使用 "icons/beasts-48.png" 路徑下的 icon。

如果你想要使用自己的 icon，icon 大小必須是 48x48 pixels，另外也可使用 96x96 pixel 來支援較高解析度的顯示。

```json
"icons": {
  "48": "icons/beasts-48.png",
  "96": "icons/beasts-96.png"
}
```

### 工具列按鈕(The toolbar button)

工具列按鈕也需要一個 icon，在 manifest.json 裡 "browser\_action" 物件中的 "default\_icon" 中告訴他要使用 "icons/beasts-32.png" 路徑下的 icon。。

準備一個命名為 "beasts-32.png" 的 icon，並存在 "beastify/icons" 資料夾中（你可以使用範例圖檔，圖檔來源：IconBeast Lite icon set，遵守使用條款來使用）。

假設你不使用 pop-up，當按下按鈕的時候就會觸發事件。假如使用 pop-up ，當按下按鈕時並不會觸發事件，取而代之會打開 pop-up。不過這邊我們想要用 pop-up，所以接來下會教你如何新增他。

### The popup

pop-up 的方法主要是讓使用者可以選擇三個動物中的其中一個。

在 beastify 下 新增一個名為 "popup" 的資料夾，該資料夾中會包含以下三個檔案：

* **`choose_beast.html`** 定義 pop-up 的顯示的內容文字
* **`choose_beast.css`** 定義 html 裡的 styles
* **`choose_beast.js`** 當使用者選擇動物後實行的腳本內容

```bash
mkdir popup
cd popup
touch choose_beast.html choose_beast.css choose_beast.js
```

#### choose\_beast.html

HTML 內容長得像這樣：

```html
<!doctype html>

<html>
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="choose\_beast.css" />
  </head>

  <body>
    <div id="popup-content">
      <div class="button beast">Frog</div>
      <div class="button beast">Turtle</div>
      <div class="button beast">Snake</div>
      <div class="button reset">Reset</div>
    </div>
    <div id="error-content" class="hidden">
      <p>Can't beastify this web page.</p>
      <p>Try a different page.</p>
    </div>
    <script src="choose\_beast.js"></script>
  </body>
</html>
```

我們在 ID 為 `"popup-content"` 的 `<div>` 元件裡建立了一個包含每種動物選項的元件。當載入 popup 發生問題時，用另外一個 ID 為 `"error-content"` 且類別定義為 `"hidden"` 的 `<div>` 元件來處理。

值得注意的是我們在這個檔案裡引用了 CSS 與 JS 檔案，就如同一般網頁。

#### choose\_beast.css

CSS 定義了 pop-up 的大小，並確保三個選項有填滿整個 pop-up，並給他們幾個基本的 style：

```css
html,
body {
  width: 100px;
}

.button {
  margin: 3% auto;
  padding: 4px;
  text-align: center;
  font-size: 1.5em;
  cursor: pointer;
}

.beast:hover {
  background-color: #cff2f2;
}

.beast {
  background-color: #e5f2f2;
}

.clear {
  background-color: #fbfbc9;
}

.clear:hover {
  background-color: #eaeac9;
}
```

#### choose\_beast.js

在 pop-up 的 JavaScript 中，我們監控著 click 事件。當按下其中一個選項後，將會讀取 js 檔到當前的瀏覽器分頁（active\_tab）中，當內容腳本被讀取後，將會發送一個訊息告訴他該選擇哪一張圖片。

```js
/\*
Given the name of a beast, get the URL to the corresponding image.
\*/
function beastNameToURL(beastName) {
  switch (beastName) {
    case "Frog":
      return browser.extension.getURL("beasts/frog.jpg");
    case "Snake":
      return browser.extension.getURL("beasts/snake.jpg");
    case "Turtle":
      return browser.extension.getURL("beasts/turtle.jpg");
  }
}

/\*
Listen for clicks in the popup.

If the click is on one of the beasts:
 Inject the "beastify.js" content script in the active tab.

 Then get the active tab and send "beastify.js" a message
 containing the URL to the chosen beast's image.

If it's on a button which contains class "clear":
 Reload the page.
 Close the popup. This is needed, as the content script malfunctions after page reloads.
\*/

document.addEventListener("click", (e) => {
  if (e.target.classList.contains("beast")) {
    var chosenBeast = e.target.textContent;
    var chosenBeastURL = beastNameToURL(chosenBeast);

    browser.tabs.executeScript(null, {
      file: "/content\_scripts/beastify.js",
    });

    var gettingActiveTab = browser.tabs.query({
      active: true,
      currentWindow: true,
    });
    gettingActiveTab.then((tabs) => {
      browser.tabs.sendMessage(tabs[0].id, { beastURL: chosenBeastURL });
    });
  } else if (e.target.classList.contains("clear")) {
    browser.tabs.reload();
    window.close();
  }
});
```

這邊使用了三個 WebExtensions API 的方法：

* `browser.tabs.executeScript` (en-US) 讀取內容腳本 "content\_scripts/beastify.js" 到當前的瀏覽器分頁裡面
* `browser.tabs.query` (en-US) 取得當前的瀏覽器分頁
* `browser.tabs.sendMessage` (en-US) 送訊息到當前的瀏覽器分頁中正在執行的內容腳本裡(beastify.js)。訊息包含了所選的動物的 URL
### 內容腳本(The content script)

在 beastify 下建立一個名為 "content\_scripts" 的資料夾，並新增一個命名為 "beastify.js" 的檔案，檔案裡的內容：

```js
/\*
beastify():
\* removes every node in the document.body,
\* then inserts the chosen beast
\* then removes itself as a listener
\*/
function beastify(request, sender, sendResponse) {
  removeEverything();
  insertBeast(request.beastURL);
  browser.runtime.onMessage.removeListener(beastify);
}

/\*
Remove every node under document.body
\*/
function removeEverything() {
  while (document.body.firstChild) {
    document.body.firstChild.remove();
  }
}

/\*
Given a URL to a beast image, create and style an IMG node pointing to
that image, then insert the node into the document.
\*/
function insertBeast(beastURL) {
  var beastImage = document.createElement("img");
  beastImage.setAttribute("src", beastURL);
  beastImage.setAttribute("style", "width: 100vw");
  beastImage.setAttribute("style", "height: 100vh");
  document.body.appendChild(beastImage);
}

/\*
Assign beastify() as a listener for messages from the extension.
\*/
browser.runtime.onMessage.addListener(beastify);
```

內容腳本中新增了一個 listener ，使其從 extension 可傳送訊息。（具體來說是從 "choose\_beast.js" 這邊） ，在 listener 中做了：

* removeEverything()：移除 `document.body` 中所有的 element ()
* insertBeast(beastURL)：新增一個 `<img>` element 並告訴它圖片的 URL，並插入到文件中
* removeListener(beastify)：刪除訊息 listener
### The beasts

最後，我們需要將動物的照片放進來

新增一個名為「beasts」的資料夾，並把三張動物的圖片放進此資料夾中，請取相對應的檔名。可以使用範例圖片，或從這邊下載：

![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension/frog.jpg)
![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension/snake.jpg)
![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension/turtle.jpg)

Testing it out
--------------

首先，請再三的確認檔案有放到相對應的資料夾中：
```

beastify/

    beasts/
        frog.jpg
        snake.jpg
        turtle.jpg

    content_scripts/
        beastify.js

    icons/
        beasts-32.png
        beasts-48.png

    popup/
        choose_beast.css
        choose_beast.html
        choose_beast.js

    manifest.json
```

開啟 Firefox 45.0，並安裝本地的 extensive 到瀏覽器裡。

在 Firefox 網址列輸入 "about:debugging" ，點選 "Load Temporary Add-on"，然後選擇你的 "manifest.json" 檔案。然後應該就會看到 extensive 的 icon 出現在工具列上了：

打開一個網頁，點選 icon，選擇一個動物的名字，將會看到網頁內容被動物的圖片取代了：

透過命令行佈署
-------

 你可以利用web-ext自動化暫時載入。
 試試看:

```bash
cd beastify
web-ext run
```


你的第一個 WebExtension - Mozilla

你的第一個 WebExtension
==================

我們會在這篇文章詳細講解 Firefox 的 WebExtension 的製作。這支附加元件會在 "mozilla.org" 網域底下的所有網頁，增加紅色外框。

範例的原始碼也放在 GitHub 喔：https://github.com/mdn/webextensions-examples/tree/main/borderify。

首先勒，你需要 Firefox 45.0 或以上的版本。

撰寫 WebExtension
---------------

新增一個資料夾，然後進到裡面：

```bash
mkdir borderify
cd borderify
```

### manifest.json

現在新增一個檔案 "manifest.json"，直接放在 "borderify" 目錄底下就行，然後把下面的程式碼塞進去：

```json
{
  "manifest\_version": 2,
  "name": "Borderify",
  "version": "1.0",

  "description": "Adds a red border to all webpages matching mozilla.org.",

  "icons": {
    "48": "icons/border-48.png"
  },

  "content\_scripts": [
    {
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["borderify.js"]
    }
  ]
}
```

* 最前面的三個 key：`manifest_version`、`name`、`version` 必須寫進去，它包含了附加元件的基本詮釋資料（metadata）。
* `description` 是可選、但最好要有：它會在附加元件管理員內標示。
* `icons` 也是可選、但最好要有：它允許附加元件指定圖示、也會在附加元件的管理員顯示。

這裡最有趣的 key 是 `content_scripts`：它告訴 Firefox 說：符合特定型態的 URL 會載入網頁的腳本。在此我們告訴 Firefox 說：所有由 "mozilla.org" 或其子域名服務的 HTTP 或 HTTPS 頁面，都要載入 "borderify.js"。

* 深入理解 content script
* 深入理解 about match pattern

**警告：** 某些情況下，你需要給附加元件指定 ID。如果需要指定附加元件 ID，請在 `manifest.json` 引入 `applications` key，並設定 `gecko.id` 屬性：

```json
"applications": {
  "gecko": {
    "id": "borderify@example.com"
  }
}
```

### icons/border-48.png

附加元件要有一個圖標。它會在附加元件管理員的附加元件清單旁邊列出來。我們的 manifest.json 已經說好了，要在 "icons/border-48.png" 那邊會有個圖標。

在 "borderify" 目錄下直接建立 "icons" 目錄，並儲存一個叫 "border-48.png" 的圖標檔。你可以用範例的這張圖標，它是從 Google Material Design 圖標集抓下來的，並使用創用 CC：姓名標示-相同方式分享授權。

如果你要用自己的圖標，它應該是 48x48 像素。你也可以針對高解析度提供 96x96 像素的圖標，這樣的話它在 manifest.json 會被指定為 `icons` 物件內的 `96` property：

```json
"icons": {
  "48": "icons/border-48.png",
  "96": "icons/border-96.png"
}
```

要不然，你也能提供 SVG 檔，它就會等比縮放。

* 深入理解指定圖標。
### borderify.js

最後，新增一個檔案叫 "borderify.js"，直接放在 "borderify" 目錄底下即可，然後一樣把下面的 code 塞進去：

```js
document.body.style.border = "5px solid red";
```

一旦網址符合 manifest.json 中 content\_scripts 所設定的模式，這段 script 就會載入，並且就像該頁自己讀入的程式碼一樣、能夠直接存取該頁上的東西。

* 深入了解 content scripts.
測試看看
----

首先，仔細檢查這些檔案是否在正確的位置：
```

borderify/
    icons/
        border-48.png
    borderify.js
    manifest.json
```

### 安裝

在 Firefox 打開 about:debugging，點選 Load Temporary Add-on 然後選擇你的 manifest.json 檔案：

現在這個附加元件就要安裝起來，但它要在你重新啟動 Firefox 後才開始。

又或者，你可以從命令列利用 web-ext 工具執行 WebExtension。

### 測試

現在去看一下 mozilla.org 還有它下面的所有網頁。你應該會看到有個紅色外框圍繞著網頁。

![Border displayed on mozilla.org](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension/border_on_mozilla_org.png)

**備註：** 不過，別把這招用在 addons.mozilla.org 上，該網域目前會阻擋 content scripts。

再做點小實驗吧。改一下腳本讓外框顏色改變，或是做其他更動。接著存檔，並按下 about:debugging 的 Reload 鍵重啟附加元件。現在你能看到更動了：

* 多了解一點附加元件的載入
打包並發送
-----

想讓別人用你的附加元件，就要把元件遞交給 Mozilla 簽署之。想獲得更多資訊，請參見 發布你的 WebExtension (en-US)。

接下來咧？
-----

現在你針對 Firefox 的 WebExtension 開發有點子的話，來看看：

* reading more about the anatomy of WebExtensions
* 再寫個更進階的 WebExtension
* 了解 WebExtensions 所提供的 JavaScript API


Anatomy of an extension - Mozilla

Anatomy of an extension
=======================

附加元件是一群檔案的集合，基於發布及安裝的目的而包裝成一個檔案。在這個章節，我們將快速地瀏覽這些可能會放在附加元件中的檔案。

manifest.json
-------------

這是每個附加元件中，唯一一個必要放置的檔案。它包含了附加元件的名稱、版本、及需要的權限等資訊，同時也提供了附加元件中其他檔案的路徑指標。

這份 manifest 也可以包含幾項其他種類檔案的指標路徑:

* Background pages: 實作長時間執行的邏輯。
* 附加元件的圖示及任何定義的按鈕。
* Sidebars, popups, and options pages: 提供各種使用者介面元件的 HTML 文件。
* Content scripts: 包含於你附加元件中的 JavaScript。你將會利用它注入到網頁中。

![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension/webextension-anatomy.png)

參考 manifest.json 參考頁取得全部的明細。

除了那些參考自 manifest 之外，附加元件可以包含額外支援的檔案作為 Extension pages 。

Background scripts 後台腳本
-----------------------

擴展套件通常需要保持長期狀態或長時間執行操作，而生命週期不依賴於任何特定網頁或瀏覽器視窗。這是後台腳本的用途。

後台腳本會在擴充套件讀取時立即執行且會持續執行直到擴充套件被禁用或是解除安裝。你可以在腳本裡使用任何 WebExtension APIs， 只要你已經申請了必要的權限。

### Specifying background scripts 載入後台腳本

你可以在"manifest.json"裡使用`background`關鍵字用來包含後台腳本。

```json
// manifest.json

"background": {
  "scripts": ["background-script.js"]
}
```

你可以同時載入後台腳本，而他們會運行於相同的環境中，就像是在一個網頁中同時載入一樣。

然而，你也可以先載入一個後台頁面，然後在後台頁面中載入腳本。這樣的做法能為後台腳本提供 ES 6 模組的支援，算是一个優點。

manifest.json：

```json
// manifest.json

"background": {
  "page": "background-page.html"
}
```

background-page.html：

```html
<!doctype html>
<html lang="zh-tw">
  <head>
    <meta charset="utf-8" />
    <script type="module" src="background-script.js"></script>
  </head>
</html>
```

### Background script environment 後台腳本環境

#### DOM APIs

後台腳本運行在一個特殊的網頁中，我們稱之為後台頁面(background pages) 。這個頁面會給予他們一個全域的變數window (en-US)，並且提供腳本使用所有的標準 DOM API。

#### WebExtension APIs

只要你請求了必要的權限 (en-US)後，後台腳本可以使用任何的WebExtension APIs 。

#### Cross-origin access 跨域請求

當後台腳本擁有host permissions (en-US) 時，便能像任何主機發送 XHR 請求。

#### Web content 網頁內容

後台腳本沒辦法直接的存取前端的網頁。然而，你可以載入 content scripts 到前端網頁後，透過 message-passing API 來與 content scripts 進行通訊 。

#### Content security policy 內容安全策略

依據内容安全策略（Content Security Policy），後台腳本不能執行一些可能有危險的操作，例如使用 `eval()` (en-US)。 詳情请参考内容安全策略 (en-US)。

Sidebars, popups, options pages 側邊欄、彈出視窗、選項頁面
---------------------------------------------

Your extension can include various user interface components whose content is defined using an HTML document:

* a sidebar is a pane that is displayed at the left-hand side of the browser window, next to the web page
* a popup (en-US) is a dialog that you can display when the user clicks on a toolbar button or address bar button (en-US)
* an options page (en-US) is a page that's shown when the user accesses your add-on's preferences in the browser's native add-ons manager.

For each of these components, you create an HTML file and point to it using a specific property in manifest.json. The HTML file can include CSS and JavaScript files, just like a normal web page.

All of these are a type of Extension pages (en-US), and unlike a normal web page, your JavaScript can use all the same privileged WebExtension APIs as your background script. They can even directly access variables in the background page using `runtime.getBackgroundPage()` (en-US).

Extension pages 擴充頁面
--------------------

You can also include HTML documents in your extension which are not attached to some predefined user interface component. Unlike the documents you might provide for sidebars, popups, or options pages, these don't have an entry in manifest.json. However, they do also get access to all the same privileged WebExtension APIs as your background script.

You'd typically load a page like this using `windows.create()` (en-US) or `tabs.create()` (en-US).

See Extension pages (en-US) to learn more.

Content scripts
---------------

Use content scripts to access and manipulate web pages. Content scripts are loaded into web pages and run in the context of that particular page.

Content scripts are extension-provided scripts which run in the context of a web page; this differs from scripts which are loaded by the page itself, including those which are provided in `<script>` elements within the page.

Content scripts can see and manipulate the page's DOM, just like normal scripts loaded by the page.

Unlike normal page scripts, they can:

* Make cross-domain XHR requests.
* Use a small subset of the WebExtension APIs (en-US).
* Exchange messages with their background scripts and can in this way indirectly access all the WebExtension APIs.

Content scripts cannot directly access normal page scripts but can exchange messages with them using the standard `window.postMessage()` (en-US) API.

Usually, when we talk about content scripts, we are referring to JavaScript, but you can inject CSS into web pages using the same mechanism.

See the content scripts article to learn more.

Web accessible resources 網頁無障礙資源
--------------------------------

Web accessible resources are resources such as images, HTML, CSS, and JavaScript that you include in the extension and want to make accessible to content scripts and page scripts. Resources which are made web-accessible can be referenced by page scripts and content scripts using a special URI scheme.

For example, if a content script wants to insert some images into web pages, you could include them in the extension and make them web accessible. Then the content script could create and append `img` (en-US) tags which reference the images via the `src` attribute.

To learn more, see the documentation for the web\_accessible\_resources (en-US) manifest.json key.


manifest.json - Mozilla

manifest.json
=============

manifest.json 是所有採用 WebExtension API 的擴充功能中、唯一一個必須包含的檔案。

你可透過 manifest.json 為擴充功能指定名稱（name）、版本（version）這類的基本元資料（metadata），也可指定擴充功能的一些相關功能，例如像是背景腳本（background scripts）、內容腳本（content scripts）、瀏覽器動作（browser actions）等等。

這是個採用 JSON 格式的檔案，但有個例外：它可接受含有 "`//`" 這種格式的註解文字。

manifest.json 可採用的鍵值如下所列：

* action
* author
* background
* browser\_action
* browser\_specific\_settings
* chrome\_settings\_overrides
* chrome\_url\_overrides
* commands
* content\_scripts
* content\_security\_policy
* declarative\_net\_request
* default\_locale
* description
* developer
* devtools\_page
* dictionaries
* externally\_connectable
* homepage\_url
* host\_permissions
* icons
* incognito
* manifest\_version
* name
* offline\_enabled
* omnibox
* optional\_permissions
* options\_page
* options\_ui
* page\_action
* permissions
* protocol\_handlers
* short\_name
* sidebar\_action
* storage
* theme
* theme\_experiment
* user\_scripts
* version
* version\_name
* web\_accessible\_resources

`"manifest_version"`、`"version"` 和 `"name"` 是一定要設定的鍵值。另外，如果有設定 "\_locales" directory ，就一定要設定 `"default_locale"` ，否則就是這兩個鍵值都不做設定。 Google Chrome, 並不支援 `"applications"` ，但針對 Firefox 48 之前及 Android 的版本，則必須設置這個鍵值。

你可透過擴充功能中的 JavaScript，藉由 `runtime.getManifest()` (en-US) 這個函式來存取擴充功能裡的 manifest ：

```js
browser.runtime.getManifest().version;
```

範例
--

以下程式碼顯示的是一般 manifest 鍵值的基本語法。請注意，這個範例並不是讓你用來直接複製貼上的，你必須根據所開發的擴充功能，填入相應的鍵值、關於擴充功能的完整範例，請參見 擴充功能範例 (en-US)。

```json
{
  "applications": {
    "gecko": {
      "id": "addon@example.com",
      "strict\_min\_version": "42.0"
    }
  },

  "background": {
    "scripts": ["jquery.js", "my-background.js"],
    "page": "my-background.html"
  },

  "browser\_action": {
    "default\_icon": {
      "19": "button/geo-19.png",
      "38": "button/geo-38.png"
    },
    "default\_title": "Whereami?",
    "default\_popup": "popup/geo.html"
  },

  "commands": {
    "toggle-feature": {
      "suggested\_key": {
        "default": "Ctrl+Shift+Y",
        "linux": "Ctrl+Shift+U"
      },
      "description": "Send a 'toggle-feature' event"
    }
  },

  "content\_security\_policy": "script-src 'self' https://example.com; object-src 'self'",

  "content\_scripts": [
    {
      "exclude\_matches": ["\*://developer.mozilla.org/\*"],
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["borderify.js"]
    }
  ],

  "default\_locale": "en",

  "description": "...",

  "icons": {
    "48": "icon.png",
    "96": "icon@2x.png"
  },

  "manifest\_version": 2,

  "name": "...",

  "page\_action": {
    "default\_icon": {
      "19": "button/geo-19.png",
      "38": "button/geo-38.png"
    },
    "default\_title": "Whereami?",
    "default\_popup": "popup/geo.html"
  },

  "permissions": ["webNavigation"],

  "version": "0.1",

  "web\_accessible\_resources": ["images/my-image.png"]
}
```

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

若想對所有的 manifest 鍵值及其子健有個完整的概念，可參見 完整 manifest.json 瀏覽器相容表 (en-US)。


內容腳本 - Mozilla

內容腳本
====

內容腳本（content script）是擴充套件的一部分，它會在在特定的網頁執行（與之相對的則是同樣屬於套件的後端腳本（background scripts）或者網站本身的腳本，像是那些那些透過 `<script>` 標籤讀取的內容）
後端腳本可以使用所有的 擴充套件 JavaScript APIs，但它們無法直接使用網頁中的內容。所以如果你的套件必須要透過 content scripts 才能使用它們。

就像一般網頁裡的 scripts 一樣，content scripts 可以透過 standard DOM APIs 存取並修改頁面內容。

Content scripts 只能使用 can only access 一小部分的擴充套件 APIs，但它們可以透過一個訊息系統來與後端腳本溝通，從而間接地使用擴充套件 APIs。

**備註：** 留意到 content scripts 目前會在 addons.mozilla.org 和 testpilot.firefox.com 中被阻擋。如果你嘗試在這些網域下的頁面注入一段 content script 會失敗並且在日誌裡記下一個 CSP (en-US) 錯誤。

**備註：** 由於錯誤 1408996，透過 `var foo` or `window.foo = "bar"` 加入 content script 的 global 作用域的值可能會消失。

讀入內容腳本
------

你可以透過下列三種方式將內容腳本讀入頁面：

1. \*\*在安裝時讀入至符合 URL 模式的頁面：\*\*透過你的 manifest.json 中的 `content_scripts` (en-US) 鍵，你可以要求瀏覽器在每次讀取 URL符合給定模式的頁面時讀入內容腳本。
2. \*\*在執行時讀入至符合 URL 模式的頁面：\*\*透過 `content_scripts` (en-US) API，你可以要求瀏覽器在每次讀取 URL符合給定模式的頁面時讀入內容腳本。這就像第一種方法，不同的是你可以在執行時增加或移除內容腳本。
3. **在執行時讀入至特定的頁籤：透過** `tabs.executeScript()` API，你可以在任何時候將內容腳本讀入特定的頁籤：舉例來說可以在使用者點擊工具列按鈕 (en-US)時給予回應。

每個套件的每個架構裡都只有一個全局作用域，所以一個內容腳本的變數可以直接被其他內容腳本使用，不管那個內容腳本是怎麼被讀入的。

透過方法（1）和方法（2）你只能把內容腳本讀入至 URL 可以用匹配模式 (en-US)來呈現的頁面中。而透過方法 3 可以把腳本讀入與套件打包在一起的頁面之中，但是你不能在像是 "about:debugging" 或 "about:addons" 這類特別的瀏覽器頁面讀入腳本。

內容腳本環境
------

### 使用 DOM

內容腳本可以像一般頁面的腳本一樣使用並修改頁面的 DOM。它們也可以偵測到所有頁面 script 對 DOM 做的更動。

然而，內容腳本看到的是「乾淨的 DOM」。這表示：

* 內容腳本看不見頁面腳本的 Javascript 變數
* 如果頁面腳本修改了原有 DOM 的屬性，內容腳本會看見原來的屬性而非被修改過的。

在 Gecko 裡，這種行爲稱爲 X 光視野 (en-US)。

舉例來說，有這樣一個網頁：

```html
<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  </head>

  <body>
    <script src="page-scripts/page-script.js"></script>
  </body>
</html>
```

"page-script.js" 做了這件事：

```js
// page-script.js

// 替DOM新增一個元素
var p = document.createElement("p");
p.textContent = "This paragraph was added by a page script.";
p.setAttribute("id", "page-script-para");
document.body.appendChild(p);

// 替 window 定義一個新的屬性
window.foo = "This global variable was added by a page script";

// 重新定義內建的 window.confirm 函數
window.confirm = function () {
  alert("The page script has also redefined 'confirm'");
};
```

接著、一個套件把 content script 插入頁面：

```js
// content-script.js

// 可以使用與修改DOM
var pageScriptPara = document.getElementById("page-script-para");
pageScriptPara.style.backgroundColor = "blue";

// 看不見 page-script 增加的屬性
console.log(window.foo); // undefined

// 看見的是原有的形式
window.confirm("Are you sure?"); // 呼叫原本的 window.confirm()
```

反過來也是一樣，頁面腳本無法看到內容腳本增加的 Javascript 屬性。

這表示我們可以預期內容腳本依賴著 DOM 屬性，不需要擔心它的變數與頁面腳本中所定義的變數衝突。

這實際的影響就是內容腳本無法使用所有頁面腳本讀入的函式庫。所以，舉例來說，如果頁面包含了 JQuery，內容腳本將無法看到它。

如果內容腳本真的想要使用 javascript 函式庫，那麼函式庫本身必須要與要使用它的內容腳本一同插入：

```json
"content\_scripts": [
  {
    "matches": ["\*://\*.mozilla.org/\*"],
    "js": ["jquery.js", "content-script.js"]
  }
]
```

注意到 Firefox 提供了一些 API 來使用被頁面腳本產生的 Javascript 物件以及對頁面腳本公開自己的 Javascript 物件。詳閱與頁面腳本共用物件 (en-US)。

### 擴充套件 APIs

除標準 DOM APIs 之外，內容腳本可以使用下列 擴充套件 APIs：

來自 `extension`:

* `getURL()` (en-US)
* `inIncognitoContext`

來自 `runtime`:

* `connect()` (en-US)
* `getManifest()` (en-US)
* `getURL()` (en-US)
* `onConnect` (en-US)
* `onMessage` (en-US)
* `sendMessage()` (en-US)

來自 `i18n` (en-US):

* `getMessage()` (en-US)
* `getAcceptLanguages()` (en-US)
* `getUILanguage()` (en-US)
* `detectLanguage()` (en-US)

來自 `storage` 的全部。

### XHR 與 Fetch

內容腳本可以透過一般的 `window.XMLHttpRequest` 與 `window.fetch()` APIs 來發出請求。

內容腳本跟套件的其他部分擁有相同的跨網域權限： 所以如果套件在 manifest.json 中透過 `permissions` 鍵要求了某一網域的使用，那麼它的內容腳本也能使用同樣的網域。

這是透過公開更多內容腳本中授權的 XHR 以及 fetch 實例來達成的。這件事情會導致標頭中不會設置 `Origin` (en-US) 與 `Referer` (en-US)的副作用，就像頁面請求自己一樣，一般會避免請求將跨來源泄露出去。從 58 版本號以後套件要傳送一些彷彿是頁面內容自己傳送的請求時可以改用 `content.XMLHttpRequest` 與 `content.fetch()`。對跨瀏覽器套件來說，這些事情的存在必須要能被做特徵檢測。

與後端腳本溝通
-------

雖然內容腳本不能直接使用大部分的 擴充套件 APIs，但是透過使用訊息 APIs 與後端腳本溝通，它們能夠間接地使用與後端腳本一樣的 APIs。

後端腳本與內容腳本的溝通模式有兩種： 你可以傳送選擇性夾帶回應的一次性訊息，也可以在兩者之間建立一個長存的連線來交換訊息。

### 一次性訊息

要傳送選擇性夾帶回應的一次性訊息，你可以使用下列 APIs：

|  | 在內容腳本處 | 在後端腳本處 |
| --- | --- | --- |
| 傳訊息 | `browser.runtime.sendMessage()` | `browser.tabs.sendMessage()` |
| 收訊息 | `browser.runtime.onMessage` | `browser.runtime.onMessage` |

舉例來說，有個監聽著頁面點擊事件的內容腳本。如果點擊對象是連結，它會傳送目標的 URL 給後端腳本：

```js
// content-script.js

window.addEventListener("click", notifyExtension);

function notifyExtension(e) {
  if (e.target.tagName != "A") {
    return;
  }
  browser.runtime.sendMessage({ url: e.target.href });
}
```

後端腳本監聽這些訊息並且透過 `notifications` (en-US) API 顯示通知：

```js
// background-script.js

browser.runtime.onMessage.addListener(notify);

function notify(message) {
  browser.notifications.create({
    type: "basic",
    iconUrl: browser.extension.getURL("link.png"),
    title: "你點了個按鈕喲！",
    message: message.url,
  });
}
```

這個範例來自 GitHub 上的 notify-link-clicks-i18n，稍微經過修改。

### 基於連線的訊息

當你在後端腳本與內容腳本間交換大量訊息時，使用一次性連線顯得沒效率。所以另一個替代方案是是在兩者間建立一個長存的連線，透過這個連線交換訊息。

兩邊都有一個 `runtime.Port` (en-US) 物件可以用來交換訊息。

建立連線你需要：

* 一邊透過 `runtime.onConnect` (en-US) 監聽連線
* 另一邊呼叫 `tabs.connect()` (en-US) （對內容腳本建立連線時）或 `runtime.connect()` (en-US) （對後端腳本建立連線時）。這會回傳一個 `runtime.Port` (en-US) 物件。
* `runtime.onConnect` (en-US) 監聽器傳送自己的 `runtime.Port` (en-US) 物件。

當兩邊都有端口後，可以透過 `runtime.Port.postMessage()` 來傳送訊息，用 `runtime.Port.onMessage` 接收訊息。

舉例來說，當這讀取完成，這個內容腳本會：

* 連線至後端腳本，並將 `Port` 儲存在一個 `myPort` 變數
* 監聽並記錄 `myPort` 的訊息
* 當使用者點擊文件時，透過 `myPort` 傳送訊息給後端腳本

```js
// content-script.js

var myPort = browser.runtime.connect({ name: "port-from-cs" });
myPort.postMessage({ greeting: "內容腳本傳喜訊" });

myPort.onMessage.addListener(function (m) {
  console.log("內容腳本收到來自後端腳本的訊息： ");
  console.log(m.greeting);
});

document.body.addEventListener("click", function () {
  myPort.postMessage({ greeting: "它們點了網頁！" });
});
```

同樣地，後端腳本會：

* 監聽來自內容腳本的連線請求
* 當它收到連線請求：
    + 將端口儲存在 `portFromCS` 這個變數
    + 透過端口傳送訊息給內容腳本
    + 開始監聽並記錄端口上的訊息
* 當使用者點擊套件的工具列按鈕時，透過 `portFromCS` 傳送訊息給內容腳本

```js
// background-script.js

var portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({ greeting: "嘿！內容腳本！" });
  portFromCS.onMessage.addListener(function (m) {
    console.log("後端腳本收到來自內容腳本的訊息：");
    console.log(m.greeting);
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(function () {
  portFromCS.postMessage({ greeting: "它們按了按鈕！" });
});
```

#### 複數內容腳本

如果你有多個內容腳本同時在溝通，你可能會想把這些連線儲存在陣列裡面。

```js
// background-script.js

var ports = [];

function connected(p) {
  ports[p.sender.tab.id] = p;
  //...
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(function () {
  ports.forEach((p) => {
    p.postMessage({ greeting: "它們按了按鈕！" });
  });
});
```

與網頁溝通
-----

雖說內容腳本預設不能存取頁面腳本產生的物件，但它們可以透過 DOM `window.postMessage` (en-US) 和 `window.addEventListener` APIs 與頁面腳本溝通。

例如：

```js
// page-script.js

var messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage({
    direction: "from-page-script",
    message: "Message from the page"
  }, "\*");
```

```js
// content-script.js

window.addEventListener("message", function (event) {
  if (
    event.source == window &&
    event.data &&
    event.data.direction == "from-page-script"
  ) {
    alert('內容腳本收到訊息： "' + event.data.message + '"');
  }
});
```

完全版的範例請查看 GitHub 上的示範頁面並按照教學做。

**警告：** 注意到當你透過這個方式跟不被信任的內容腳本互動時要非常小心。套件有很強的權限，惡意網頁可以輕易地騙出這些權限。

舉個簡單的例子，假設一接收訊息的內容腳本長這樣：

```js
// content-script.js

window.addEventListener("message", function (event) {
  if (
    event.source == window &&
    event.data.direction &&
    event.data.direction == "from-page-script"
  ) {
    eval(event.data.message);
  }
});
```

如此一來頁面腳本可以使用包含內容腳本全部權限的程式碼。

在內容腳本中使用 eval()
---------------

在 Chrome 裡， `eval()` (en-US) 只會在內容腳本而不會在頁面腳本裡執行。

在 Firefox 裡：

* 如果你呼叫 `eval()`，它會在內容腳本中執行
* 如果你呼叫 `window.eval()`，它會在頁面腳本中執行

例如，試想有一個內容腳本長這樣：

```js
// content-script.js

window.eval("window.x = 1;");
eval("window.y = 2");

console.log(`In content script, window.x: ${window.x}`);
console.log(`In content script, window.y: ${window.y}`);

window.postMessage(
  {
    message: "check",
  },
  "\*",
);
```

這段程式碼透過 `window.eval()` 和 `eval()` 建立了些變數 x 和 y 、記錄下它們的值並且傳訊息給頁面。

接收訊息這邊，頁面腳本記錄下一樣的值：

```js
window.addEventListener("message", function (event) {
  if (event.source === window && event.data && event.data.message === "check") {
    console.log(`In page script, window.x: ${window.x}`);
    console.log(`In page script, window.y: ${window.y}`);
  }
});
```

在 Chrome 裡，這會產出這樣的結果：
```

In content script, window.x: 1
In content script, window.y: 2
In page script, window.x: undefined
In page script, window.y: undefined
```

而在 Firefox 裡會產生這些：
```

In content script, window.x: undefined
In content script, window.y: 2
In page script, window.x: 1
In page script, window.y: undefined
```

這些也適用於 `setTimeout()` (en-US)、`setInterval()`、與 `Function()` (en-US)。

當在頁面執行程式碼時一定要小一萬個心，頁面的環境有可能被惡意的網頁所控制，它們可以重新定義與你互動的物件來作出一些出乎意料的行爲：

```js
// page.js 重新定義 console.log

var original = console.log;

console.log = function () {
  original(true);
};
```

```js
// content-script.js 呼叫被重新定義的版本

window.eval("console.log(false)");
```


用戶介面 - Mozilla

用戶介面
====

套件 APIs 提供了幾種介面來完成對用戶的功能。下方是那些介面的概述，每種用戶介面都有更詳細的資訊可以查閱。

**備註：** 爲了使用這些 UI 元件在套件裡提供優秀的用戶體驗，建議閱讀用戶體驗最佳實踐文章。

| 可用介面 | 敘述 | 範例 |
| --- | --- | --- |
| 工具列按鈕 | 一個瀏覽器工具列上的按鈕，被點擊時會送出事件給套件。預設的情況下在所有頁籤都能看到此按鈕。 | Example showing a toolbar button (browser action). |
| 附帶彈出視窗 (en-US)的工具列按鈕 | 一個按鈕上的彈出視窗，當按鈕被點擊時展開。彈出視窗被一個HTML文件來定義。 | Example of the pop-up on a toolbar button |
| 網址列按鈕 | 一個網址列上的按鈕，點擊時傳送事件給套件。預設的情況下，在所有的頁籤中此按鈕都會被隱藏。 | Example showing an address bar button (page action)  |
| 附帶彈出視窗 (en-US)的網址列按鈕 | 網址列按鈕上的一個按鈕，當按鈕被點擊時展開，彈出視窗被一個HTML文件來定義。 | Example of a popup on the address bar button |
| 快捷選單 | 在一個或多個瀏覽器快捷選單中的選單項目、核取方塊、選項按鈕。另外，選單可以透過增加分隔線來組成。當選單項目被點擊時傳送一個事件給套件。 | Example of content menu items added by a WebExtension, from the context-menu-demo example |
| 側邊欄 | 一個顯示在網頁旁邊的HTML文件，每頁可以顯示獨立的內容。側邊欄會在用戶安裝套件時打開，然後根據用戶對側邊欄的可視選項開關。側邊欄裡的用戶互動由它的HTML文件來控制。 | Example of a sidebar |
| 選項頁面 (en-US) | 一個使你可以定義用戶能修改的偏好設定的頁面。用戶可以透過瀏覽器的套件管理畫面進到這裡。 | Example showing the options page content added in the favorite colors example. |
| 套件頁面 | 透過套件裡的網頁來在視窗或頁籤內提供表單、幫助訊息或任何需要的內容。 | Example of a simple bundled page displayed as a detached panel. |
| 通知 (en-US) | 透過作業系統的機制顯示的短暫的通知。當用戶點擊通知或通知關閉時（不論自動關閉或用戶手動關閉）時傳送事件給套件。 | Example of an extension triggered system notification |
| 網址列建議 (en-US) | 當用戶輸入關鍵字時提供自訂的網址列建議。 | Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions. |
| 開發者工具面板 | 一個包含相關HTML文件的頁籤顯示在瀏覽器的開發者工具裡。 | Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions. |

下面是一些關於建立這些用戶介面的詳細教學：

* 在工具列加入一個按鈕 (en-US)
* 建立設定頁面 (en-US)
* 擴充開發者工具 (en-US)


何謂附加元件？ - Mozilla

何謂附加元件？
=======

附加元件（Add-ons）擴展並修改了瀏覽器的功能。他們使用標準的網路技術 ──JavaScript、HTML、以及 CSS、還有一些專用的 JavaScript API── 寫成。除此之外，附加元件可以給瀏覽器添加新功能、或是改變特定網站的外觀或內容。

Firefox 的附加元件開發基於能跨瀏覽器的 WebExtensions APIs ，在很大的程度上相容於和 Google Chrome 與 Opera 瀏覽器所支持的 extension API 。大多數情況下，針對這些瀏覽器所撰寫的 Extension 只要些許修改就能在 Firefox 或是 Microsoft Edge 執行，也與 multiprocess Firefox 完全相容。

在過去，你可以使用三種系統開發 Firefox 附加元件： XUL/XPCOM overlays、bootstrapped extensions、或是 Add-on SDK。但 2017 年 11 月底之後，WebExtensions 將成為唯一開發 Firefox 附加元件的方式，而其他方式會被廢棄。

如果你有任何想法或問題，甚至是需要協助轉換舊附加元件到新系統，你可以在 Add-ons Discourse、IRC 的 #webextensions 或 Telegram MozTW dev/add-on 找到我們。

接下來呢？
-----

* 一些附加元件的範例，請參看 Example WebExtensions。
* 學習附加元件的結構，請參看 解析 WebExtension.
* 一個簡單的附加元件開發流程，請參看 你的第一個 WebExtension。


cookies - Mozilla

cookies
=======

讓擴充套件可以取得、設定 cookies 資訊，並監控其變動。
使用此 API 前，必須先在 manifest.json 檔案中加入「cookies」這項 API 權限宣告，也必須以 host 權限宣告將要存取 Cookies 的網站列入。參見 Cookie 權限一節。

型別
--

`cookies.Cookie` (en-US)

代表一個 HTTP cookie 的相關資訊。

`cookies.CookieStore`

代表瀏覽器中的 cookie 存放空間。

`cookies.OnChangedCause`

代表觸發 cookie 資料變動的原因。

方法
--

`cookies.get()` (en-US)

取回單一 cookie 的相關資訊。

`cookies.getAll()` (en-US)

取回符合設定條件的所有 cookies 資訊。

`cookies.set()` (en-US)

為 cookie 設定資料。如果目前已有相同的 cookies，則會覆寫原本的 cookie 資料。

`cookies.remove()` (en-US)

刪除某特定名稱的 cookie。

`cookies.getAllCookieStores()` (en-US)

列出目前所有的 cookie 存放空間。

事件處理程序
------

`cookies.onChanged`

當 cookie 設定或刪除時觸發。

權限
--

使用此 API 前，擴充套件應於 manifest.json 設定檔中指明需要「cookies」API 權限，亦須以 host 權限宣告指明需要存取 cookies 的網站清單。此後，符合 host 權限宣告的 URL 所能讀寫的任何 cookies，該擴充套件即可讀取。比方說：

`http://*.example.com/`

若套件有這樣的 host 權限宣告，即可：

* 讀取 `www.example.com` 任何路徑下的非安全 cookie。
* 寫入 `www.example.com` 任何路徑下的安全或非安全 cookie。

但*不能*：

* 讀取 `www.example.com` 下的安全 cookie。

`http://www.example.com/`

若套件有這樣的 host 權限宣告，即可：

* 讀取 `www.example.com` 任何路徑下的非安全 cookie。
* 讀取 `.example.com` 任何路徑下的非安全 cookie。
* 寫入 `www.example.com` 任何路徑下的安全或非安全 cookie。
* 寫入 `.example.com` 任何路徑下的安全或非安全 cookie。

但*不能*：

* 寫入 `foo.example.com` 的 cookie。
* 寫入 `foo.www.example.com` 的 cookie。

`*://*.example.com/`

若套件有這樣的 host 權限宣告，即可：

* 讀、寫 `www.example.com` 任何路徑下的安全或非安全 cookie。

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### Edge 不相容資訊

Edge 不支援 promises，請使用回呼（callback）函式處理。

Example extensions
------------------

* cookie-bg-picker
* list-cookies

**備註：** 此 API 基於 Chromium 的 `chrome.cookies` API 而來，文件改作自 Chromium 程式碼裡的 `cookies.json`。

Microsoft Edge 的相容資訊來自微軟公司，原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。


storage - Mozilla

storage
=======

讓套件可以存讀資料以及監聽儲存項目的更動。

儲存系統基於 Web Storage API (en-US)，有一些不同，包括：

* 非同步
* 值的作用域在套件而不是某個特定的網域（後端的所有腳本與內容腳本都可用同樣的鍵值）。
* 儲存的值可以是任何的 JSON-ifiable 值而並非只能是 `String`。這包括了： `陣列`、`物件` (en-US)。但只有在內容可以被以 JSON 表示的時候，這表示不包含 DOM 節點。你不需要特地把值轉爲 JSON `Strings`來儲存它們，它們在內部就是以 JSON 來表示的。
* 同一個 API 呼叫中可以設置或取得複數鍵值。

要使用這個 API 你必須在 manifest.json 裡面加入 "storage" 的權限 (en-US)。

每個套件都有自己的儲存空間，它們可以被切分爲不同種類的儲存。

雖然這個 API 與`Window.localStorage`很相似，建議你不要在套件裡使用 `Window.localStorage` 儲存套件相關資料。Firefox 在用戶由於隱私問題清除歷史記錄與資料時會清除 localStorage API 儲存的資料，而 `storage.local` API 儲存的則會留著。

**備註：** 儲存空間不會被加密，所以你不應該把它們用來儲存用戶的機密資料。

型別
--

`storage.StorageArea` (en-US)

表示儲存空間的物件。

`storage.StorageChange` (en-US)

表示儲存空間變化的物件。

屬性
--

`storage` 有三個屬性，各自表示不同種類的儲存空間。

`storage.sync` (en-US)

表示 `sync` 儲存空間。`sync` 儲存空間裡的項目會被瀏覽器同步，所以可以跨裝置在所有已登入瀏覽器實例裡面使用。

`storage.local`

表示 `local` 儲存空間。`local` 儲存空間裡的項目會被侷限在安裝套件的機器上。

`storage.managed` (en-US)

表示 `managed` 儲存空間。`managed` 儲存空間的項目由網域管理者設置而且對套件唯讀，修改這項會導致錯誤。

事件
--

`storage.onChanged` (en-US)

當儲存空間裡的一個或更多項目被修改時觸發。

瀏覽器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Example extensions
------------------

* annotate-page
* favourite-colour
* forget-it
* navigation-stats
* proxy-blocker
* quicknote
* stored-credentials

**備註：** This API is based on Chromium's `chrome.storage` API. This documentation is derived from `storage.json` in the Chromium code.

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.


cookies.OnChangedCause - Mozilla

cookies.OnChangedCause
======================

`cookies` API 的 `OnChangedCause` 型別，代表觸發 cookie 資料變動的原因。

型別
--

此型別的所有值都是字串（string）。可用值包括：

`evicted`

由於垃圾回收（garbage collection）而被刪除的 cookie。

`expired`

由於過期而被刪除的 cookie。

`explicit`

透過顯式呼叫（explicit call）`cookies.remove()` (en-US) 而被插入或刪除的 cookie。

`expired_overwrite`

被已過期（already-expired expiration date）cookie 所覆寫的 cookie。

`overwrite`

A call to `cookies.set()` (en-US) overwrote this cookie with a different one.

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

示例
--

你可以在 cookie 變更的時候監聽被通知的 `cookies.onChanged` 事件。此監聽器 passed 含有 `cause` 屬性，值為 `OnChangeCaused` 字串的 `changeInfo` 物件：

```js
browser.cookies.onChanged.addListener(function (changeInfo) {
  console.log(
    "Cookie changed: " +
      "\n \* Cookie: " +
      JSON.stringify(changeInfo.cookie) +
      "\n \* Cause: " +
      changeInfo.cause +
      "\n \* Removed: " +
      changeInfo.removed,
  );
});
```

**備註：** 此 API 基於 Chromium 的 `chrome.cookies` API 而來，文件改作自 Chromium 程式碼裡的 `cookies.json`。

Microsoft Edge 的相容資訊來自微軟公司，原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。


cookies.onChanged - Mozilla

cookies.onChanged
=================

`cookies` API 的 `onChanged` 事件會在 cookie 設定或刪除時觸發。

請注意，更新 cookie 的屬性要透過以下兩個步驟實做：

1. 首先，要更新的 cookie 會先被刪掉，並產生一個 `overwrite` 的 `cookies.OnChangedCause` 提醒。
2. 接著，帶著更新數值的新 cookie 會被寫進去，並產生第二個 `explicit` 的 `cookies.OnChangedCause` 提醒。
語法
--

```js
browser.cookies.onChanged.addListener(listener);
browser.cookies.onChanged.removeListener(listener);
browser.cookies.onChanged.hasListener(listener);
```

此 API 也能以 `browser.cookies.onChanged.*` 運行。

此事件有以下函式：

`addListener(callback)`

給此事件添加監聽器（listener）。

`removeListener(listener)`

停止監聽此事件。`listener` 參數是要移除的監聽器。

`hasListener(listener)`

檢查此事件的 `listener` 是否被監聽了。若有監聽，回傳 `true`，否則回傳 `false`。

addListener 語法
--------------

### 參數

`callback`

能被呼叫的 callback 函式會在此事件發生的時候觸發。函式會 passed 以下參數：

`changeInfo`

一個含有觸發事件資訊的 `object`。它有兩個屬性：

`removed`

一個 `boolean`。如果 cookie 被刪除則為 `true`，否則為 `false`。

`cookie`

一個 `cookies.Cookie` (en-US) 物件。含有被設定、或被刪除的 cookie 資訊。

`cause`

一個 `cookies.OnChangedCause` 數值。含有 cookie 被改變的潛在原因。

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

示例
--

本範例監聽 `onChanged` 事件並紀錄由 `changeInfo` 參數傳來的資訊：

```js
browser.cookies.onChanged.addListener(function (changeInfo) {
  console.log(
    "Cookie changed: " +
      "\n \* Cookie: " +
      JSON.stringify(changeInfo.cookie) +
      "\n \* Cause: " +
      changeInfo.cause +
      "\n \* Removed: " +
      changeInfo.removed,
  );
});
```

### Example extensions

* cookie-bg-picker

**備註：** 此 API 基於 Chromium 的 `chrome.cookies` API 而來，文件改作自 Chromium 程式碼裡的 `cookies.json`。

Microsoft Edge 的相容資訊來自微軟公司，原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。


cookies.CookieStore - Mozilla

cookies.CookieStore
===================

`cookies` API 的 `CookieStore` 型別代表瀏覽器中的 cookie 存放空間。

不同瀏覽模式（browsing mode）的視窗，有不同的 cookie 存放空間：例如隱私/隱身模式的視窗，會使用來自非隱私/隱身模式視窗的個別 cookie 存放空間。

型別
--

此型別的值都是物件，並包含以下屬性：

`id`

`string`，代表 cookie 存放空間內的唯一識別號（identifier）。

`tabIds`

`integers` 的 `array`，識別所有分享此 cookie 存放空間的瀏覽頁籤。

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

示例
--

在以下程式碼片段內，`cookies.getAllCookieStores()` (en-US) 用來查找瀏覽器內，所有目前能用 cookie 存放空間，並列出每個 cookie 存放空間的 ID、還有分享此 cookie 存放空間的頁籤。

```js
function logStores(cookieStores) {
  for (store of cookieStores) {
    console.log(`Cookie store: ${store.id}\n Tab IDs: ${store.tabIds}`);
  }
}

var getting = browser.cookies.getAllCookieStores();
getting.then(logStores);
```

**備註：** 此 API 基於 Chromium 的 `chrome.cookies` API 而來，文件改作自 Chromium 程式碼裡的 `cookies.json`。

Microsoft Edge 的相容資訊來自微軟公司，原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。


storage.local - Mozilla

storage.local
=============

代表 `local` 儲存空間。通常 `local` 裡面的東西，會放在套件安裝的地方。

瀏覽器可能會限制套件本地可儲存的資料數量：

* Chrome 限制套件內用到此 API 資料的上限為 5MB，除非有 unlimitedStorage 權限。
* 56 版以後的 Firefox 將能要求 unlimitedStorage 權限。目前 Firefox 還沒有限制套件內的資料上限，但這功能會在未來引入：因此，如果可能會儲存大容量的資料，最好要實做 unlimitedStorage 的請求。

如果套件被移除、相關的儲存資料也會一併移除。

在 Firefox 內，你可以透過 about:config 內設定 keepUuidOnUninstall 與 keepStorageOnUninstall 為 `true` 以避免瀏覽器在移除套件時，一併移除相關的儲存資料。這個功能是為了方便開發者除錯，套件本身無法改變這個設定。

雖然這 API 與 `Window.localStorage` 相似，但不建議在套件內使用 `Window.localStorage`。在某些情況下，用戶會出於隱私上的理由，要求 Firefox 清理瀏覽紀錄與資料，這其中就包含使用 localStorage API 的資料。另一方面，storage.local API 的資料，在這種情況下會予以保留。

方法
--

`local` 物件實做了定義於 `storage.StorageArea` (en-US) 類別的方法：

`storage.StorageArea.get()` (en-US)

取得一個或多個源自儲存空間的項目。

`storage.StorageArea.getBytesInUse()` (en-US)

取得儲存空間內，一個或多個已為項目所使用的容量。單位為 byte。

`storage.StorageArea.set()` (en-US)

Stores one or more items in the storage area. If the item already exists, its value will be updated. When you set a value, the `storage.onChanged` (en-US) event will fire.

`storage.StorageArea.remove()` (en-US)

刪除一個或多個儲存空間內的項目。

`storage.StorageArea.clear()` (en-US)

刪除所有儲存空間內的項目。

瀏覽器相容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### Example extensions

* annotate-page
* forget-it
* navigation-stats
* proxy-blocker
* quicknote
* stored-credentials

**備註：** This API is based on Chromium's `chrome.storage` API. This documentation is derived from `storage.json` in the Chromium code.

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.


開發工具面板 - Mozilla

開發工具面板
======

**備註：** Firefox 54 以後可以使用這個功能。

當套件提供開發者使用的工具時，可以以一個瀏覽器開發工具的新面板的形式在開發者工具裡添加一個 UI。

![Simple example showing the addition of "My panel" to the Developer Tools tabs.](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels/developer_panel_tab.png)

指定開發工具面板
--------

開發工具面板可以透過 `devtools.panels` (en-US) API 添加，因此這必須在特別的開發工具頁面執行。

透過在套件的 manifest.json 添加 `devtools_page` (en-US) 鍵並提供 HTML 檔案來添加開發工具頁面：

```json
"devtools\_page": "devtools-page.html"
```

在開發工具頁面，呼叫腳本會添加開發工具面板：

```html
<body>
  <script src="devtools.js"></script>
</body>
```

在腳本裡，藉由指定面板標題、圖示、HTML 檔案來建立開發工具：

```js
function handleShown() {
  console.log("panel is being shown");
}

function handleHidden() {
  console.log("panel is being hidden");
}

browser.devtools.panels
  .create(
    "My Panel", // title
    "icons/star.png", // icon
    "devtools/panel/panel.html", // content
  )
  .then((newPanel) => {
    newPanel.onShown.addListener(handleShown);
    newPanel.onHidden.addListener(handleHidden);
  });
```

套件現在可以在檢測器視窗透過 `devtools.inspectedWindow.eval()` (en-US) 或透過後端腳本傳送訊息來插入內容腳本兩種方式執行。你可以在擴充開發者工具 (en-US)找到更多相關訊息。

開發面板設計
------

更多關於如何設計符合 Firefox 風格的開發者面板，請查看文件光子設計系統。

圖示
--

更多關於建立開發者工具面板圖示的細節，請查看文件光子設計系統的圖示學。

範例
--

GitHub 上的 webextensions-examples 程式庫包含了建立開發工具面板的 devtools-panels 範例。


側邊欄 - Mozilla

側邊欄
===

側邊欄是一個顯示在瀏覽器視窗上、網頁旁邊的面板。瀏覽器提供能讓用戶看見目前可用的側邊欄並且擇一顯示的 UI。例如，Firefox 有一個 "檢視 > 側邊欄" 的選單。一次只能有一個側邊欄顯示，而那個側邊欄會顯示在所有的頁籤以及瀏覽器視窗。

瀏覽器可能包含了一些內建的側邊欄。例如，Firefox 包含了一個可以跟書籤互動的側邊欄：

![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars/bookmarks-sidebar.png)在 manifest.json 裡用 `sidebar_action` 鍵可以替瀏覽器添加側邊欄。它會被列在內建的側邊欄旁邊，而用戶可以透過與內建側邊欄一模一樣的機制來打開它。

就像工具列按鈕一樣，你藉由 HTML 文件指定側邊欄的內容。當用戶打開側邊欄，側邊欄的文件會被讀取到每個開著的瀏覽器視窗。每個視窗都各自獲取文件的實例，當新的視窗被開啓，他們也會獲取自己的側邊欄實例。

你可以用`sidebarAction.setPanel()` (en-US)函數設置某個頁籤專屬的文件。側邊欄會透過`windows.getCurrent()` (en-US) API 找出它隸屬的視窗 :

```js
// sidebar.js
browser.windows.getCurrent({ populate: true }).then((windowInfo) => {
  myWindowId = windowInfo.id;
});
```

如果側邊欄要在不同的視窗顯示不同內容這會很有用。範例請看 "annotate-page" 範例。

側邊欄文件與後端腳本以及彈出視窗享有一樣的權限。他們可以透過`runtime.getBackgroundPage()` (en-US)直接讀取後端頁面（只要側邊欄隸屬於隱私模式的視窗），並且可以透過一些 messaging APIs 與內容腳本或原生應用互動，像是`tabs.sendMessage()` (en-US)與`runtime.sendNativeMessage()` (en-US)。

側邊欄文件會在瀏覽器視窗關閉或用戶關閉側邊欄時被卸載。這代表不像後端腳本，側邊欄文件並不總是保持讀入的狀態。但是不像工具列按鈕，他們可以在用戶與網頁互動時保持讀入。

當定義著側邊欄的套件被首次安裝時，側邊欄 2 會自動開啓。這是爲了幫助用戶瞭解這個套件包含了一個側邊欄。註：套件無法程式化地開啓側邊欄，側邊欄只能由用戶開啓。

指定側邊欄
-----

要指定側邊欄，在 manifest.json 裡透過 `sidebar_action` 鍵定義文件、標題以及圖示：

```json
"sidebar\_action": {
  "default\_title": "My sidebar",
  "default\_panel": "sidebar.html",
  "default\_icon": "sidebar\_icon.png"
}
```

你可以透過`sidebarAction` (en-US) API 程式化地更改標題、面板以及圖示。

標題與圖示會在任一個瀏覽器提供的 UI 中顯示，像是 Firefox 裡的 "檢視 > 側邊欄" 選單。

側邊欄設計
-----

更多如何設計符合 Firefox 風格的側邊欄網頁細節，請查看文件光子設計系統。

範例
--

GitHub 上的 webextensions-examples 程式庫包含了建立側邊欄的 annotate-page 範例。


快捷選單項 - Mozilla

快捷選單項
=====

這個用戶介面添加一個或多個項目到瀏覽器的快捷選單。這是用戶在網頁上點擊右鍵時出現的選單。頁籤也可以透過 browser.menus API 使用快捷選單。

![Example of content menu items added by a WebExtension, from the context-menu-demo example](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items/context_menu_example.png)

你可以用這個介面來顯示一些跟特定瀏覽器或網頁內容相關的功能。舉例來說，當用戶在圖片上按右鍵時提供圖片編輯器的功能或者在反白內容上按右鍵時提供儲存頁面內容的功能。你可以對選單添加普通的選單項目、核取方塊、單選按鈕組以及分隔線。選單項目透過`contextMenus.create` (en-US)添加後透過它會顯示在所有瀏覽器頁籤，但是你可以透過`contextMenus.remove` (en-US)來移除它。

指定快捷選單項目
--------

透過`contextMenus` (en-US) API 可以程式化地管理快捷選單項目。然而，你必須請求 `contextMenus` 的權限才能使用這些 API 的好處。

```json
"permissions": ["contextMenus"]
```

現在你可以在你套件的後端腳本處添加（修改／刪除）選單項目。建立一個選單項目你要指定 id，標題以及它應該隸屬於哪個選單：

```js
browser.contextMenus.create(
  {
    id: "log-selection",
    title: browser.i18n.getMessage("contextMenuItemSelectionLogger"),
    contexts: ["selection"],
  },
  onCreated,
);
```

接著你的套件會監聽選單項目的點擊。送出有關項目點擊、點擊環境以及發生點擊頁籤的資訊可以用來使用恰當的套件功能。

```js
browser.contextMenus.onClicked.addListener(function(info, tab) {
  switch (info.menuItemId) {
    case "log-selection":
      console.log(info.selectionText);
      break;
    ...
  }
})
```

圖示
--

更多關於建立快捷選單圖示的細節請查看文件光子設計系統的圖示學。

範例
--

GitHub 上的webextensions-examples 程式庫包含了兩個建立快捷選單的範例：

* menu-demo 替瀏覽器的快捷選單添加幾個項目。
* context-menu-copy-link-with-types 替連結添加一個快捷選單項，以純文字或 rich HTML 的形式複製連結的 UR。


工具列按鈕 - Mozilla

工具列按鈕
=====

 根據工具列按鈕 (en-US)，這個用戶介面是一個加到瀏覽器工具列的按鈕。用戶透過點擊按鈕來與你的套件互動。

 ![](/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Toolbar_button/browser-action.png)

工具列按鈕與網址列按鈕非常相似。關於差別以及何時該使用的指引，詳閱工具列按鈕。

詳細指定工具列按鈕
---------

透過在 manifest.json 中使用 `browser_action` (en-US) 鍵來定義工具列按鈕的屬性：

```json
"browser\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "我在哪？"
}
```

唯一一個強制的鍵只有 `default_icon`。

指定工具列按鈕的方式有兩種： 有彈出視窗跟沒有彈出視窗。如果你不指定彈出視窗，當用戶點擊按鈕事件會被傳送到套件，而套件透過 `browserAction.onClicked` (en-US) 監聽：

```js
browser.browserAction.onClicked.addListener(handleClick);
```

如果你指定彈出視窗，點擊事件不會被傳送，取而代之當用戶點擊按鈕時彈出視窗會被展開。用戶可以跟彈出視窗互動且當用戶點擊了彈出視窗外側它會自動關閉。更多建立與管理彈出視窗的細節請查看彈出視窗文章。

註： 你的套件只能有一個工具列按鈕。

你可以透過 `browserAction` (en-US) API 程式化地更改任何工具列按鈕的屬性。

圖示
--

更多關於建立工具列按鈕使用的圖示，請查看文件光子設計系統裡的圖示學。

範例
--

GitHub 上的擴充套件範例程式庫包含兩個建立工具列按鈕的範例：

* bookmark-it 使用不含彈出視窗的工具列按鈕。
* beastify 使用包含彈出視窗的工具列按鈕。


作者 - Mozilla

作者
==

|  |  |
| --- | --- |
| 型別 | `String` |
| 強制 | No |
| 範例 |
```json
"author": "cool puppy"
```
 |

套件作者，用來顯示在瀏覽器的用戶介面中。如果有提供 developer 鍵而且裡面包含 "name" 屬性，那會覆蓋 author 鍵。不能指定多個作者。

這是一個可侷限的屬性。

範例
--

```json
"author": "cool puppy"
```

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


applications - Mozilla

applications
============

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | 通常是不強制（請看你什麼時候會需要 Add-on ID？）。在 Firefox 48（桌面）前以及Android版Firefox 是強制的。 |
| 範例 |
```json
"applications": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0"
  }
}
```
 |

敘述
--

`applications` 鍵包含了詳細描述特定應用的鍵。

目前這只包含了一個鍵，`gecko`，它包含 4 個 string 參數：

* `id` 是套件 ID。Firefox 48 以後爲選擇性，48 前爲強制。需要什麼來指定 add-on ID 請查看套件與 Add-on ID。
* `strict_min_version`：支持的最舊 Gecko 版本。在這個欄位版本號包含 "\*" 是不合法的。預設是 "42a1"。
* `strict_max_version`： 支持的最新 Gecko 版本。如果套件安裝的 Firefox 版本超過這個版本號則套件會被禁用或不被允許安裝。預設爲 "\*"，表示禁用最新支持版本檢查。
* `update_url` 是套件更新 manifest。備：連結必須以 "https" 開頭。這個鍵用來自己管理套件更新（不透過套件管理器）。

查看可用 Gecko 版本。

### 套件 ID 格式

套件 ID 格式必須是下列其中一種：

* GUID
* 寫得像信箱地址的字串：`extensionname@example.org`

後者比較容易產生與操作。小心，在這裡使用真實信箱地址可能會引來垃圾信件。

例如：

```json
"id": "extensionname@example.org",

"id": "{daf44bf7-a45e-4450-979c-91cf07434c3d}"
```

範例
--

包含所有可用鍵的範例。註：大多數套件會忽略 `strict_max_version` 和 `update_url`。

```json
"applications": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0",
    "strict\_max\_version": "50.\*",
    "update\_url": "https://example.com/updates.json"
  }
}
```

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


options_ui - Mozilla

options\_ui
===========

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | No |
| 範例 |
```json
"options\_ui": {
  "page": "options/options.html"
}
```
 |

用 `options_ui` 鍵來定義套件的選項頁面 (en-US)。

選項頁面包含了套件的設定。用戶可以從套件管理員進入這個畫面，而你可以用`runtime.openOptionsPage()` (en-US)打開它。

指定 `options_ui` 爲一個與套件打包在一起的 HTML 檔案路徑。就像一般的網頁一樣，HTML 檔案可包含 CSS 與 JavaScript 檔案。跟普通頁面不同的是，它可以使用所有被授權 (en-US)的套件 APIs。 不過，它執行的作用域不同於你的後端腳本。

 如果你想在**選項頁面**與**後端腳本**的 JavaScript 裡**共用**資料或函數，你可以透過用`extension.getBackgroundPage()` (en-US)與後端腳本的 Window (en-US) 關聯、用`extension.getViews()` (en-US)與任何套件內腳本的`Window` (en-US)關聯來實現。你也可以透過 `runtime.sendMessage()` (en-US)、 `runtime.onMessage` (en-US)，跟（或）`runtime.connect()` (en-US)在選項頁面與後端的頁面的 JavaScript 之間溝通。
 後者（或是`runtime.Port` (en-US)）也可以用來在後端腳本與\*\*內容腳本\*\*之間共用選項。

一般要儲存選項頁面的選項變動時，你要可能會用 storage API、storage.sync (en-US)（如果你想要在所有用戶登入的瀏覽器實例之間同步設定的話），或者透過 storage.local （如果設定是針對目前身份或機器）。而如果你希望你的後端腳本（或內容腳本）監聽該變化，你可以加上 storage.onChanged (en-US) 監聽器。

語法
--

`options_ui` 鍵是一個包含了下列內容的物件：

| Name | Type | Description |
| --- | --- | --- |
| `browser\_style (en-US)` | `Boolean` | 可選，預設爲 `true`。

 用這個來替你的頁面引入一個樣式表，使你的頁面與瀏覽器UI以及其他用
 `browser_style`
 的套件看起來一致。雖然它預設是`true`還是建議你加入這個屬性。

 在 Firefox 裡，樣式表可以在 chrome://browser/content/extension.css 或
 chrome://browser/content/extension-mac.css（OS
 X）查看。設定尺寸的時候注意到這個樣式表目前會做這個設定`box-sizing: border-box`
 （查看 box-sizing）。

Firefox風格指南寫到一些你可以應用到彈出視窗裡面的元素上來變成特定樣式的class。 |
| `open_in_tab` | `Boolean` | 可選，預設爲 `false`。

 如果設爲
 `true`，選項頁面會在普通的瀏覽器頁籤開啓而不是整合在瀏覽器的套件管理員裡。
  |
| `page` | `String` | 強制。
包含選項頁面細項的HTML檔案路徑。
這個路徑是 manifest.json 的相對路徑。 |

範例
--

```json
"options\_ui": {
    "page": "options/options.html"
  }
```

瀏覽器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Browser styles (en-US)


homepage_url - Mozilla

homepage\_url
=============

|  |  |
| --- | --- |
| 型別 | `String` |
| 強制 | No |
| 範例 |
```json
"homepage\_url": "https://example.org/my-addon"
```
 |

套件首頁的 URL。

如果有 developer 鍵且它包含 "url" 屬性，這會覆蓋 homepage\_url 鍵。

這是一個可侷限的屬性。

範例
--

```json
"homepage\_url": "https://github.com/mdn/webextensions-examples/tree/main/beastify"
```

瀏覽器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


background - Mozilla

background
==========

|  |  |
| --- | --- |
| 型別 | `Object` |
| 強制 | No |
| 範例 |
```json
"background": {
  "scripts": ["background.js"]
}
```
 |

用 `background` 鍵來引入一個或多個後端腳本，還有一個選擇性的套件後端頁面。

後端腳本是用來放置一些需要維護長期狀態或是進行長期操作的程式碼，它麼的生命週期跟任何網頁或瀏覽器視窗是獨立的。

後端腳本會在套件一被讀取就被讀入，一直到套件被禁用或移除才會卸載。只要你有請求對應的權限 (en-US)你可以在這個腳本裡使用任何擴充套件 APIs。

更多細節，查看套件解析的"後端頁面"章節。

`background` 鍵是一個物件，可能包含下列二屬性其中之一，兩者都是選擇性的：

|  |  |
| --- | --- |
| `"scripts"` |
 一個字串組成的陣列，每個都是 JavaScript 原始碼的路徑。路徑是
 manifest.json 檔案自身的相對路徑。這些是會被套件讀取的後端腳本。

腳本共用全局 `window`。
腳本根據陣列裡的順序讀入。

**註：**Firefox 版本50以前有一個錯誤當 Firefox
 除錯器開啓時，腳本並不總是按照陣列裡的順序讀入。要解決這個錯誤，你可以用
 `"page"` 屬性並且在頁面中透過
 `<script>` 標籤讀入後端腳本。這個錯誤在 Firefox 50
 被修正，從那開始腳本總是會依照陣列中的順序讀入。

**備註：**
 如果你想要用`<script>標籤`從遠端取得一個腳本（例如
 `<script src =
"https://code.jquery.com/jquery-1.7.1.min.js">`），你必須要修改套件 manifest.json 中的
 `content_security_policy` 鍵。

 |
| `"page"` |
 如果你指定
 `"scripts"`，那麼爲了讓你的腳本執行一個空白頁面會被建立。

 如果頁面中需要某些內容，你可以用
 `"page"` 選項定義自己的頁面。

 如果你用了這個屬性，你就不能透過
 `"scripts"`
 來指定後端腳本。但是你可以像一般的網頁一樣在頁面中引入你自己的腳本。
  |

範例
--

```json
"background": {
    "scripts": ["jquery.js", "my-background.js"]
  }
```

讀取兩個後端腳本。

```json
"background": {
    "page": "my-background.html"
  }
```

讀取一個自訂的後端頁面。

瀏覽器兼容
-----

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Web 遊戲開發介紹 - 遊戲開發

Web 遊戲開發介紹
==========

現有 Web 環境已成為多元的平台，不只可建構令人驚艷的高品質遊戲，也是發佈這些遊戲的重要媒介。可供撰寫的遊種類......
現有的 Web 技術再搭配最新版瀏覽器，就能打造出絕佳的 Web 遊戲，而且我們講的可不是用 Flash® 寫的簡單卡牌遊戲，或是多人的社交遊戲而已。卻是可打趴一堆平面遊戲的 3D 動作射擊或角色扮演遊戲。多虧 JavaScript 的即時 (Just-in-time，JIT) 技術與新 API 雙雙大幅提升其效能，你所撰寫的遊戲已可於瀏覽器 (或支援 HTML5 的裝置) 中執行，卻又不致犧牲任何效能。

HTML5 遊戲平台
----------

如同 Mozilla 常說的「Web 即是平台」，你可將 Web 想像為較佳的遊戲平台。接著就來看看 Web 平台的核心：

| 功能 | 技術 |
| --- | --- |
| **音效** | Web Audio API |
| **圖形** | WebGL (en-US) (OpenGL ES 2.0) |
| **輸入** | 觸控事件、Gamepad API (en-US)、裝置感測器、WebRTC (en-US)、Full Screen API、Pointer Lock API |
| **程式語言** | JavaScript（或 C/C++ 可透過Emscripten 編譯為 JavaScript） |
| **網路連線** | WebRTC (en-US) 及/或 WebSockets |
| **儲存功能** | IndexedDB 或雲端 |
| **Web** | HTML、CSS、SVG（還有更多！） |

商業案例
----

不論你是獨立或大型遊戲工作室的開發者，你都應該將 Web 作為自己下一個遊戲專案的系統。先來看看 Web 能對你提供多少優勢：

1. Web 無遠弗屆，而用 HTML5 撰寫的遊戲可自由在桌機、平板電腦、智慧電視、智慧型手機上執行。
2. 可獲得更好的行銷與露出機會。你不再限制於某個 App 商店才能推廣自己的 App；反而能透過 Web 上的所有媒體推銷遊戲，並利用 Web 的串連與分享效率接觸到新客戶。
3. 你能控制「付款」這個重要的作業。之前只要你的遊戲放在某個生態系統中，就必須支付超過 30% 的收益給該系統。但現在你可選擇自己喜歡的 App 訂價與付款服務。
4. 同樣的，你也能自行控制 App 的更新頻率，而不再需要枯等別人審核你的重要修正檔，還不知道今天還明天才能上架。
5. 控制你的分析方式！你能蒐集自己所需的資料，或可選擇你所愛用的第三方，進而獲得你的銷售資訊以及所觸及的消費族群；不需再讓別人幫你決定分析方法。
6. 你能進一步管理自己與消費者之間的關係，不再受限於 App 商城的機制而取得篩選過的反饋意見。也不需再經過中間人，就能以自己的方式和消費者直接交流。
7. 玩家隨時隨地都能暢玩你的遊戲。因為 Web 無所不在，消費者能在自己的手機、平板電腦、家裡桌機、辦公室電腦，或任何地方觀看遊戲進度。
遊戲開發者所應知道的 Web 技術
-----------------

 我們要為開發者提供 API 的相關資訊，了解 Web 帶來的絕妙開發功能。
 以下只列舉出其中數項：

Full Screen API

此簡易 API 可讓遊戲全螢幕運作，提供玩家絕佳的動作體驗。

Gamepad API (en-US)

如果要讓遊戲搭配搖桿或其他類型的控制器，就用這個 API。

HTML 與 CSS

這兩種技術可用以建立遊戲的使用者介面，並設定其風格與配置方式。部分的 HTML 即為 `<canvas>` 元素，可直接建構 2D 圖形。

HTML audio (en-US)

`<audio>` (en-US) 元素可輕鬆播放簡易音效與音樂。如果需要進一步效果，可參閱 Web Audio API 達到真正的音訊處理效能！

IndexedDB

此強大的資料儲存 API，可將使用者的資料保存於電腦或其他裝置之上，亦可於本端儲存遊戲資料與其他資訊；如此可避免每次都需再下載資料一次。即使目前處於無網路連線的狀態 (例如飛機上長達數個小時的旅程...)，也同樣可以玩遊戲 。

JavaScript

JavaScript 就是 Web 上使用的程式語言，可於現有瀏覽器上達到絕佳速度，且目前還在不斷的提升。你可寫出遊戲的程式碼，或可透過如 Emscripten 或 Asm.js 的技術，輕鬆移植現有的遊戲。

Pointer Lock API

Pointer Lock API 可鎖定遊戲介面中的滑鼠或其他指向裝置。取代之前的絕對游標定位，現可接收座標差而得到更精確的使用者動作，並避免使用者突然在他處輸入，卻遺漏了重要動作。

SVG (Scalable Vector Graphics，可縮放向量圖形)

可建構向量圖形，根據裝置畫面的解析度而順暢調整。

Typed Array（具型別陣列）

JavaScript 的具型別陣列，可讓你在 JavaScript 中存取原始的二進位資料。如此可讓你設定 GL 紋理 (Texture)、遊戲資料，或其他物件。甚至非原生 JavaScript 格式的亦可處理。

Web Audio API

此 API 可透過 JavaScript 程式碼控制音訊的回播、合成、操作等作業，讓你建構絕妙音效並即時播放音樂。

WebGL (en-US)

可於 Web 內容中建立高效能、硬體加速的 3D (與 2D) 圖像。此為 Web 所支援的 OpenGL ES 2.0 實作。

WebRTC (en-US)

WebRTC (Real-Time Communications) API 可控制音訊與視訊資料 (包含視訊會議)，並能在兩名使用者之間來回傳輸其他應用程式的資料。想讓玩家能一邊爆怪物的頭還一邊交談？就用這個 API 吧。

WebSockets

WebSocket API 可讓你的 App 或網站連上伺服器，進而即時來回傳輸資料。適用於多人遊戲、聊天服務等。

Web Workers

Workers 可讓你分配背景執行緒，執行本身所屬的 JavaScript 程式碼，藉以利用新的多核心處理器。

XMLHttpRequest and File API

整合的 XMLHttpRequest 與 File API，可你從 Web 伺服器接收或傳送所需的任何資料 (別因為「XML」搞混了)。如此能順利下載新的遊戲關卡與圖片，藉以來回傳輸非即時的遊戲狀態資訊。


只使用 JavaScript 的 2D 打磚塊遊戲 - 遊戲開發

只使用 JavaScript 的 2D 打磚塊遊戲
=========================

* 次頁 »

本文將帶你逐步做出簡單的 MDN 打磚塊遊戲。除了只用 JavaScript 寫成之外，也透過 HTML5 的 `<canvas>` 繪製。

每個步驟均提供可測試修改的實際範例，讓你能看到各個步驟所產生的影響。你將了解該如何使用 `<canvas>` 元件完成基礎的遊戲機制，例如繪製 (Render)、移動圖形、碰撞偵測、操控機制、輸贏狀態等。

若要能充分了解此一系列文章，你應具備基礎至中等的 JavaScript 知識。結束此教學之後即可寫出自己的簡易網頁遊戲。

![Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives.](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/mdn-breakout-gameplay.png)

課程細節
----

所有課程和其他不同版本的 MDN 打磚塊遊戲，均可至 GitHub 找到：

1. 建立 Canvas 並繪製
2. 讓球移動
3. 讓球反彈
4. 搖桿和鍵盤控制 (en-US)
5. 判斷遊戲結束 (en-US)
6. 建立磚塊場地 (en-US)
7. 碰撞偵測 (en-US)
8. 更新分數並判斷輸贏 (en-US)
9. 滑鼠控制 (en-US)
10. 結束 (en-US)

 若一開始就單純使用 JavaScript，將能學到紮實的網頁遊戲開發知識。往後則可自由選擇你自己愛用的框架 (Framework) 來完成專案。
 框架同樣是由 JavaScript 寫成的工具。因此在用框架開發之前，能先了解程式語言本身將有助於了解框架內部所發生的事。框架可加快開發速度並代勞遊戲中某些無聊的部份，但若遊戲運作得不如預期，你都可試著除錯或撰寫純 JavaScript 的解決方案。

**備註：** 如果你對 2D 網頁遊戲開發的遊戲函式庫有興趣，可參考此〈使用剖析器 (Phaser) 的打磚塊遊戲 (en-US)〉系列相關文章 。

**備註：** 此系列文章也能當做行動遊戲開發工作坊的教材。如果你想講解一般的遊戲開發，則可利用此教學為基礎的〈Gamedev Canvas Content Kit〉。

下一步
---

好吧！讓我們開始第一章 — 建立 Canvas 並繪製。

* 次頁 »


讓球碰到牆壁後反彈 - 遊戲開發

讓球碰到牆壁後反彈
=========

* « 前頁
* 次頁 » (en-US)

這是 Gamedev Canvas tutorial (en-US)中的第三步 你可以在以下的連結中查看原始碼Gamedev-Canvas-workshop/lesson3.html.

很好我們現在可以讓球移動了, 但目前他會在移動到邊緣後消失, 這使我們少了點樂趣! 為了解決這個問題我們稍後會加入一些碰撞處理 ( later (en-US) ) 使球可以再碰到邊緣時反彈.

簡單的碰撞偵測
-------

為了偵測碰撞的發生，我們將檢查球是否接觸(相撞)牆壁，如果有碰到，我們將改變球的行進方向。

為了方便計算，我們定義一變數 `ballRadius` 代表球的半徑。在你程式碼宣告變數的地方加入以下內容:

```js
var ballRadius = 10;
```

接著更新繪製球的 `drawBall()` 函數，加入以下內容:

```js
ctx.arc(x, y, ballRadius, 0, Math.PI \* 2);
```

從頂部和底部反彈
--------

總共有四面牆壁會與球發生碰撞 — 首先處理上方的牆壁，我們在每個影格檢查球是否有接觸到 Canvas 上方壁面 —如果是的話，我們將扭轉球的運動，所以它將開始在相反的方向移動，並保持在可見邊界。記住坐標係從左上角開始，我們可以得到這樣的東西：

```js
if (y + dy < 0) {
  dy = -dy;
}
```

如果球位置的 Y 值低於零，改變 Y 軸上的運動的方向，通過設置它等於本身，扭轉。如果球是向上移動的速度為每幀的 2 個像素，現在它將移動「了」的速度為- 2 像素，這實際上等於在每幀的 2 個像素的速度向下移動。

上面的代碼將處理球反彈的頂部邊緣，所以現在讓我們想想下邊緣：

```js
if (y + dy > canvas.height) {
  dy = -dy;
}
```

 如果球的 Y 位置大於畫布的高度（請記住，我們計算從左上角的 Y 值，所以頂部邊緣開始在 0 和底部邊緣是在 480 像素，畫布的高度），然後通過反轉的 Y 軸運動的底部邊緣，如前。
 我們可以將這兩個語句為一個節省代碼冗長：

```js
if (y + dy > canvas.height || y + dy < 0) {
  dy = -dy;
}
```

如果兩個語句中的一個是真的，則反轉球的運動。

從左邊和右邊反彈
--------

我們有頂部和底部邊緣覆蓋，所以讓我們想想左，右的。它實際上是非常相似的，你所要做的就是重複 X 而不是 Y 的陳述：

```js
if (x + dx > canvas.width || x + dx < 0) {
  dx = -dx;
}

if (y + dy > canvas.height || y + dy < 0) {
  dy = -dy;
}
```

在這一點上你應該插入上面的代碼塊到 draw()功能，在關閉括號。

球不斷地消失在牆上！
----------

測試你的代碼在這一點上，你會留下深刻的印象-現在我們有一個球，反彈了所有四個邊緣的畫布！然而，我們有另一個問題-當球擊中每一個牆，它下沉到它略有改變方向：

![](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls/ball-in-wall.png)

這是因為我們計算的牆壁和球的中心的碰撞點，而我們應該做它的圓周。球應該反彈後，如果接觸牆，而不是當它已經在牆上的一半，所以讓我們調整我們的陳述有點包括。更新你添加到的最後一個代碼：

```js
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
  dx = -dx;
}
if (y + dy > canvas.height - ballRadius || y + dy < ballRadius) {
  dy = -dy;
}
```

當球的中心與牆的邊緣之間的距離與球的半徑完全相同時，它會改變運動方向。從邊緣減去一個半徑的寬度以及添加到另一個方向給我們在碰撞檢測在中球彈回牆壁的印象。

比較你的程式碼
-------

讓我們用剛剛所學的再次檢查完成的程式碼，並把玩一下：

**備註：** 每次球撞到牆上時嘗試改變球的顏色為隨機的顏色。

下一步
---

我們現在已經進入了舞台，我們的球是移動和停留在遊戲板上。 在第四章中，我們將討論實現一個可控制的球拍 - 參見 Paddle and keyboard controls (en-US).

* « 前頁
* 次頁 » (en-US)


讓球移動 - 遊戲開發

讓球移動
====

* « 前頁
* 次頁 »

這一篇是Gamedev Canvas tutorial (en-US)十個步驟中的第二步。當完成此步驟你的程式碼應該會與Gamedev-Canvas-workshop/lesson2.html差不多

完成上一個步驟，你已經知道如何畫出一顆球，現在讓他動起來吧。藉由繪製球在螢幕上然後再清除，然後在每個影格中繪製球在偏移一點點的位置上（如果在同一個位置上就等於沒動），造成物體移動的感覺，就如同電影中物體移動的方式。

定義一個繪製用的迴圈
----------

為了固定更新 canvas 繪圖區域的每一個影格，我們需要定義一個繪製函式（drawing function），它將會重複執行，用不同的變數改變球的位置或其他物的位置。重複執行一個函式，其中使用 JavaScript timing function，像是 `setInterval()` (en-US) 或是 `requestAnimationFrame()`.

除了前兩行的 JavaScript，其餘的都刪除，並將以下的程式碼加入在前兩行之後。draw()函數每十毫秒會被 setInterval 執行一次:

```js
function draw() {
  // drawing code
}
setInterval(draw, 10);
```

因為 `setInterval` 無限循環的特性， `draw()` 函數將會每 10 毫秒被呼叫一次除非我們將它停止。 現在，讓我們來把球畫出來 — 將以下程式碼加入到 `draw()` 函數內:

```js
ctx.beginPath();
ctx.arc(50, 50, 10, 0, Math.PI \* 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
```

現在將你的程式碼更新 — 球將會在每個影格被重新繪製.

讓球動起來
-----

由於球並沒有移動，你沒有辦法察覺到它正不斷的被重新繪製。讓我們稍作修改。首先，取代掉原本寫死的位置(50,50)，我們宣告變數 x 和 y 讓球從 Canvas 正中央的底部出發，接著利用 x 和 y 來定義球應該被畫在哪裡。

首先將下面兩行程式碼加到你的 `draw()` 函數用以定義 `x` 和 `y`:

```js
var x = canvas.width / 2;
var y = canvas.height - 30;
```

接著修改 `draw()` 函數，在 `arc()` (en-US) 方法裡使用了變數 x 和 y，就像下面被強調的那行程式碼：

```js
function draw() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}
```

再來是最重要的部分: 在每個影格被繪製出來後，我們想要對 x 和 y 增加一數值，讓球看起來好像在移動一樣。讓我們來定義這個數值為 dx 以及 dy，並且分別設為 2 以及 -2。將以下程式碼添加到你定義 x 和 y 的地方:

```js
var dx = 2;
var dy = -2;
```

最後，在每個影格中我們利用 dx 和 dy 來更新 x 和 y 的數值，球就會在每次更新後被畫到不同的位置。將最後兩行程式碼加到你的 draw()函數內:

```js
function draw() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
  x += dx;
  y += dy;
}
```

儲存你的程式碼並在瀏覽器重新整理。程式正常運作，雖然球似乎留下的他的蹤跡:

![](/zh-TW/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball/ball-trail.png)

在每個影格開始前清除 canvas
-----------------

由於我們在每個影格繪製新的球之前並沒有把舊的清除掉，讓他看起來像留下了一條痕跡。別擔心，其實是有方法可以把 canvas 清除掉: `clearRect()` (en-US). 這個方法需要 4 個參數: 前兩個參數代表了長方形左上角的 x 和 y 座標，後兩個參數代表了長方形右下角的 x 和 y 座標。之前在這長方形範圍內所繪製的東西將會被清除掉。

將以下強調的程式碼加到 `draw()` 函數內:

```js
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
  x += dx;
  y += dy;
}
```

將程式碼儲存並重新整理瀏覽器，這次球沒有再留下痕跡了。每 10 毫秒 canvas 會被清除，球將會被畫在指定的位置上，且 x 和 y 會更新以用在下一個影格.

整理程式碼
-----

再接續幾個章節我們會持續增加 `draw()` 函數內的指令，讓我們儘可能的維持程式的簡潔度。讓我們把繪製球的程式碼獨立為一個函數。

將原本的 draw() 函數拆成以下兩個函數:

```js
function drawBall() {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI \* 2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  x += dx;
  y += dy;
}
```

比較你的程式碼
-------

以下為到目前為止完整的程式碼，你可以核對並試著操作以幫助你更瞭解他的運作方式:

Exercise: 練習改變球的移動速度或行進方向。

下一步
---

我們繪製了球並且讓他可以移動，但他仍會消失在 canvas 的邊緣。在第三章我們將會實作 讓球碰到牆壁後反彈 (en-US).

* « 前頁
* 次頁 »


建立Canvas並畫出 - 遊戲開發

建立Canvas並畫出
===========

* « 前頁
* 次頁 »

這是Gamedev Canvas tutorial (en-US)十個步驟的第一步。你可以這份教學的原始碼，當你完成這份教學你的程式碼應該跟Gamedev-Canvas-workshop/lesson1.html差不多。

在開始撰寫遊戲功能之前，我們先建構在遊戲中負責渲染的基礎結構。渲染可透過 HTML 的`<canvas>` 元件完成。

遊戲的 HTML
--------

當整個遊戲透過`<canvas>` 元件渲染時，HTML 檔案結構就會相當簡單。用你最喜歡的文字編輯器打開新的 HTML 檔，將它命名為`index.html並存在適當的位置上，再將下面的的程式碼貼到index.html中`:

```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Gamedev Canvas Workshop</title>
    <style>
 \* {
 padding: 0;
 margin: 0;
 }
 canvas {
 background: #eee;
 display: block;
 margin: 0 auto;
 }
 </style>
  </head>
  <body>
    <canvas id="myCanvas" width="480" height="320"></canvas>

    <script>
 // JavaScript code goes here
 </script>
  </body>
</html>
```

在 header 中設定了文字編碼、以及`<title>`和一些 CSS 樣式。在 body 中包含`<canvas>`與`<script>`，前者將用來渲染遊戲畫面，後者將用來撰寫 JavaScript 程式控制渲染。`<canvas>` 元件有個 `id` 為 `myCanvas` 方便當作參考(reference，如許多程式語言中的變數)讓我們設定它的寬度為 480 pixels 與高度 320 pixels，這份教學中全部的 JavaScript 程式碼都會寫在 `<script>` 開始標記與 `</script>` 結束標記中間。

Canvas 基礎
---------

為了能夠順利渲染圖形在`<canvas>`元件中，獲得`<canvas>`元件的參考。請將下列的程式碼加在`<script>`開始標記的後面。

```js
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
```

我們將`<canvas>`元件的參考存成變數 canvas 為了未來使用。建立 ctx 變數儲存"2D 渲染環境"，ctx 變數實際拿來繪製 Canvas 的工具。

以下片段的程式範例在 canvas 上印出紅色正方形。將以下的程式加在上面 J 的 avaScript 程式碼之後，再用瀏覽器打開`index.html`測試。

```js
ctx.beginPath();
ctx.rect(20, 40, 50, 50);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
```

所有的指令都介於`beginPath()` (en-US)與`closePath()` (en-US)。我們用`rect()` (en-US)定義了一個矩形，`rect()` (en-US)中前兩個數值代表左上角的座標。在上面的情況中，矩形距離左邊 20 pixels，距離畫面上方 40 pixels，50 pixels 寬，50 pixels 高，形成完美的正方形。`fillStyle` (en-US)屬性所儲存的顏色會被`fill()` (en-US)方法用來塗滿正方形，在此為塗上紅色。

不僅矩形— 以下的程式碼印出綠色的圓形。試著將程式碼加在 JavaScript 底部，存檔在重新整理瀏覽器中的`index.html`:

```js
ctx.beginPath();
ctx.arc(240, 160, 20, 0, Math.PI \* 2, false);
ctx.fillStyle = "green";
ctx.fill();
ctx.closePath();
```

如同你看到的我們再次使用了`beginPath()` (en-US)與`closePath()` (en-US)。在它們中間最重要的程式碼是`arc()` (en-US)。`arc()` (en-US)用到六個參數(依序介紹)：

* `圓弧中心的x、y座標`
* 圓弧的半徑
* 圓弧開始和結束的角度(從開始到結束的角度, 以弧度表示)
* 繪製的方向(`false`代表順時針方向, 預設或 true 為逆時針方向) 最後一個參數並非必要

`fillStyle` (en-US)看起來與之前不同，原因就像 CSS 一樣可以用 16 進位、顏色關鍵字、`rgba()函式等其他可用的顏色指定方法。`

不但有`fill()` (en-US)填滿圖形，還有 `stroke()` (en-US) 專門為外輪廓線上色。也試著加入下面的 JavaScript 程式碼吧:

```js
ctx.beginPath();
ctx.rect(160, 10, 100, 40);
ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
ctx.stroke();
ctx.closePath();
```

上面的程式碼印出藍色邊框的空心矩形，由於在`rgba()函式的`alpha 通道，藍色邊框呈現半透明。

比較你的程式碼
-------

這裡第一課的有全部原始碼，在 JSFiddle 上實際運行:

**備註：** 練習改變物體的大小和顏色

下一步
---

現在我們已經設定基本的 HTML 並且學了一些 canvas 知識 ，讓我們接著下去第二章實做如何在遊戲中移動球 (en-US)。 (en-US)

* « 前頁
* 次頁 »


伺服端網站程式設計 - 學習該如何開發 Web

伺服端網站程式設計
=========

***動態網站***–***伺服端網站程式設計***是一連串有關如何建立動態網站的模組：動態網站可以針對 HTTP 請求，發送客製化的資訊。這些模組將介紹伺服端網站程式設計：還有以初學者的角度，來教你怎麼使用 Django (Python) 與 Express (Node.js/JavaScript) 來架設基本的動態網路程式。

大多數主流網站會使用伺服端技術，以根據需要呈現動態資料。例如說，來想想亞馬遜（Amazon）上架多少商品、還有臉書（Facebook）貼了多少動態。如果都用靜態頁面來呈現這些內容，開發就會毫無效率可言。因此，我們會使用靜態技術（HTML、CSS、JavaScript）來顯示靜態模板；並在需要時，動態更新模板內的資料。一如你在逛亞馬遜時，看著五花八門的產品一般。

在當今的 Web development 的世界，我們強烈建議學習怎麼開發伺服端網站程式。

學習路徑
----

學習伺服端網站程式設計通常比用戶端網站程式設計簡單，因為動態網站比較傾向執行多次相似的操作（像是從資料庫擷取資料並放到頁面上、驗證用戶輸入的資料並存到資料庫、檢查登入用戶權限之類的）、使用框架建立網站能讓上述操作、以及其他常見操作變得簡單許多。

基本的程式概念（或是理解特定的語言）會很有用，但不是必須的。同樣地，精於用戶端網站程式設計不是必須，但它能在前端開發時，幫你做得更好。

首先你要知道「web 是怎麼作動的」。我們建議先看看這些文章：

* 何謂網路伺服器？
* 建立網站需要什麼軟體？ (en-US)
* 如何把檔案傳到伺服器？ (en-US)

有了基本觀念後，就可以開始去學習模組章節的東西了。

模組
--

本章節包含了以下模組。你首先要從第一個模組開始，再循序漸進，學習接下來的模組。這些模組將告訴你如何與訪間最熱門的其中兩個伺服器端框架共事。

伺服器端程式設計起步走

本模組會提供與技術無關的伺服器資訊，像是「那什麼？」、「和用戶端有啥不同？」、「有用嗎？」之類的。本模組也會概述一些比較熱門的伺服器端 web 框架、並告訴你如何選擇。最後，我們還會概述有關伺服器服務的安全性問題。

Django 網站框架 (Python)

Django 以 Python 寫成，是個非常熱門的伺服器端 web 框架。本模組會講解 Django 是好框架的理由、如何建立開發環境、還有如何處理常見工作。

Express web framework (Node.js/JavaScript)

Express 以 JavaScript 寫成、並在 node.js 執行環境執行。它也是個非常熱門的伺服器端 web 框架。本模組會講解一些有關本框架的重要優點、也同樣會講解如何建立開發環境、還有如何處理常見工作。

參見
--

不用框架的 Node 伺服器 (en-US)

如果不想用框架的話，這篇文章會告訴你如何使用純 Node.js 提供簡易的靜態檔案。


無障礙網頁 - 學習該如何開發 Web

無障礙網頁
=====

如果要當 web 開發者，學會 HTML、CSS、JavaScript 是很重要的。不過除此之外，你還要學得更多：你需要**負責任地**運用這些技術，才能讓所有讀者都能使用你的網頁。要達成這點，本模塊將展示一般最佳實做（在 HTML、CSS、JavaScript 有示範）、跨瀏覽器測試、還有其他啟動的要點。

概觀
--

When someone describes a site as "accessible," they mean that any user can use all its features and content, regardless of how the user accesses the web — even and especially users with physical or mental impairments.

* Sites should be accessible to keyboard, mouse, and touch screen users, and any other way users access the web, including screen readers and voice assistants like Alexa and Google Home.
* Applications should be understandable and usable by people regardless of auditory, visual, physical, or cognitive abilities.
* Sites should also not cause harm: web features like motion can cause migraines or epileptic seizures.

**By default, HTML is accessible, if used correctly.** Web accessibility involves ensuring that content remains accessible, regardless of who and how the web is accessed.

先決條件
----

要理解本模塊的概念，最少理解 HTML、CSS、JavaScript 是個好主意。如果在學習相關技術時學習會更好。

**備註：** 如果使用的設備無法讓你建立自己的文件，可以試著在 JSBin 或 Glitch 這種程式撰寫網站，執行大多數範例。

教學
--

何謂無障礙網頁？

這篇文章針對何謂無障礙網頁，起了一個好開頭。這模塊包含了要考慮哪些族群以及理由、不同族群會用什麼工具和 Web 互動、還有怎麼把無障礙網頁導入 Web 開發工作流程。

HTML：無障礙網頁的好開始 (en-US)

只要確保在任何時候，正確的 HTML 元素都用於正確的目的，就能消除各種網頁的障礙。這篇文章詳述 HTML 如何確保網頁無障礙。

充分實踐 CSS 與 JavaScript 的無障礙 (en-US)

如果 CSS 與 JavaScript 使用得當，將可以為無障礙網頁提供助力……反過來的話，就會嚴重影響無障礙體驗。這篇文章詳述如何在內容複雜的情況下，確保能充分實踐 CSS 與 JavaScript 的無障礙。

WAI-ARIA 基礎

從之前的文章來看，有時製作要涉及到非語意的 HTML 還有動態 JavaScript 更新技術……等，會令複雜的 UI 控制變得很困難。WAI-ARIA 正是為了解決此一問題而生。它對瀏覽器和輔助技術添加進一步的語意，讓用戶能知道發生了什麼事。我們將介紹如何在基本層面使用此技術，以提昇無障礙。

無障礙多媒體 (en-US)

會導致無障礙網頁出問題的另一個根源是多媒體：影片、聲音、圖片等內容，需要有合適的文字替代，以便輔助技術和它的用戶能夠理解。我們將在這篇文章中闡明作法。

行動無障礙網頁 (en-US)

隨著行動設備訪問漸受歡迎、還有像是 iOS 與 Android 這般熱門平台，已經具備完善的輔助工具，考慮到如何在這些平台上實踐無障礙網頁，就變得十分重要。這篇文章將討論行動裝置特有的無障礙網頁相關議題。

評估
--

無障礙網頁偵錯 (en-US)

要評估本模塊，我們會提出一些簡單的網站，你需要偵測有哪些無障礙的問題並修復之。

參見
--

* Start Building Accessible Web Applications Today：Marcy Sutton 所作的一套優秀教學影片。
* Deque University resources：包含程式碼範例、螢幕閱讀器參考、或是其他有用的資源。
* WebAIM resources：有教學、便覽、工具……等。
* Web Accessibility Evaluation Tools List - includes a list of web accessibility evaluation tools.


常見問題 - 學習該如何開發 Web

常見問題
====

學習專區的這個區塊被設計來為可能遇到的常見問題提供解答，這並非核心學習路線的必要途徑（譬如 HTML 或 CSS 的教學文章）。這些文章為獨立成群。

Web 的運作方式
---------

這個區塊包含網路運作機制——有關網路環境及其如何運作的一般知識。

網際網路如何運作？ (en-US)

**網際網路**是網路的骨幹，讓網路成為現實的技術基礎架構。簡單來說，網際網路是讓所有電腦互相溝通的超大型網絡。這篇文章用最淺顯的文字探討它是如何運作的。

網頁、網站、網路伺服器及搜尋引擎有什麼區別？ (en-US)

這篇文章講述網路相關的各種概念：網頁、網站、網路伺服器及搜尋引擎。這些術語常常被新手混淆或誤用。讓我們來認識它們各自的意思吧！

URL 是什麼？ (en-US)

結合 Hypertext (en-US) 與 HTTP，URL 是最重要的網路概念之一。它是被 browsers 用來獲取發佈到網路的任何資源的機制。

網域名稱是什麼？ (en-US)

網域名稱是網際網路基礎架構中關鍵的一部份，它提供指向網際網路上可被找到的網路伺服器一個可被人讀懂的地址。

網路伺服器是什麼？

「網路伺服器」指能橫跨網路將網站提供給用戶端的硬體或軟體——或是軟硬體結合。這篇文章探討網路伺服器怎麼運作，以及為何它很重要。

超連結是什麼？ (en-US)

這篇文章中，我們會學到超連結是什麼，以及為何它很重要。

工具與設定
-----

有關能用來建立網站的工具/軟體的問題。

在網路上做事要花多少錢？ (en-US)

當你啟動一個網站時，可能不用花錢，可能成本高得嚇人。這篇文章中我們會探討每個細節的成本，以及你花一筆錢（或者不花錢）能獲得什麼。

架一個網站需要什麼軟體？ (en-US)

這篇文章解釋當你編輯、上傳或檢視網站時需要用到的軟體。

哪個文字編輯器比較適合？ (en-US)

這篇文章中，我們列出為網路開發選擇與安裝文字編輯器時一些值得思考的重點。

瀏覽器開發者工具是什麼？ (en-US)

每個瀏覽器皆有一系列對 HTML、CSS 及其它網路程式碼除錯的開發工具。這篇文章將解釋如何使用你的瀏覽器開發工具的基本功能。

如何確保我的網站會正常運作？ (en-US)

你將你的網站發佈到網路上了——非常好！但是你確定它能正確運行嗎？這篇文章提供一些基本的問題解決步驟。

如何架設本地端測試伺服器 (en-US)

這篇文章將解釋如何在你的電腦上設置一個簡單的本地端測試伺服器，以及基本使用方式。

如何上傳檔案到網路伺服器？ (en-US)

這篇文章示範如何透過 FTP 工具將你的網站發佈到網路上——這是將網站放到線上，讓別人可從他們的電腦存取的常見方式之一。

如何使用 GitHub 頁面？ (en-US)

這篇文章提供如何透過 Github 頁面發佈內容的基礎指南。

如何在 Google App Engine 上架設網站？ (en-US)

想找個地方架設你的網站嗎？這是一篇手把手教你在 Google App Engine 上架設網站的指南。

為網站除錯及改良效能需要什麼工具？

本系列文章教你如何用 Firefox 開發者工具來除錯與改良網站效能，將會運用工具來檢視記憶體使用量、JavaScript Call Tree、被渲染的 DOM 節點數及其它東西。

設計與網頁親和力
--------

這個區塊列舉有關美感、網頁架構、網頁親和力技巧等等的問題。

如何開始設計我的網站？ (en-US)

這篇文章會探討每個專案最重要的第一步：定義你想透過這個網站達成什麼目標？

常見網頁布局包含什麼？ (en-US)

當你為你的網站設計網頁時，最好對一些常見的布局有所了解。這篇文章帶你遍覽幾個典型的網頁布局，仔細檢視組成它的每個部份。

網頁親和力是什麼？ (en-US)

這篇文章將介紹網頁親和力背後的基本概念。

如何設計能兼容所有使用者的網站？ (en-US)

這篇文章提供幫助你設計能兼容所有使用者的網站的基本技巧。

哪些 HTML 功能可以增進網頁親和力？ (en-US)

這篇文章講述讓網頁對不同的身心障礙更顯親和的特定 HTML 功能。

HTML、CSS 與 JavaScript 問題
------------------------

有關 HTML、CSS 與 JavaScript 的常見問題解決方式，可以參考以下文章：

* 使用 HTML 解決常見問題
* 使用 CSS 解決常見問題
* 使用 JavaScript 解決常見問題


工具與測試 - 學習該如何開發 Web

工具與測試
=====

當你開始對網路核心技術（如 HTML、CSS、JavaScript）感到熟悉、累積經驗、閱讀更多資源、學到更多技巧和竅門時，你會碰上一大堆的工具，從 CSS 與 JavaScript 開始，到測試並自動化程式、還有一堆眉眉角角。等到你網路專案變得龐大而複雜時，你可能會想要用上某些工具、並針對你的程式碼，撰寫些可信賴的測試計劃。學習專區的這一區，旨在給你做出明智抉擇的所需。

網路產業的職場令人興奮，但也並非全無弊病。當今用於建置網站的核心技術已相當成熟，然新功能日益漸增、而方便使用，並由那些技術為基礎的新工具也不斷問世。最重要的是，我們還要把跨瀏覽器支援銘記於心，並確保我們的程式碼遵循專案的最佳做法，以確保它們能在不同用戶使用的瀏覽器和設備上運行，身心障礙人士亦可使用。

決定該用什麼工具可能是個困難的過程，因此我們寫了這幾篇文章，來告訴你可以使用什麼樣的工具、它們能為你做什麼，以及如何針對產業的偏好利用之。

**備註：** 因為隨時都會有新工具問世、舊工具退出，我們刻意把內容寫得盡可能中立：我們希望先關注這些工具所能完成，最重要的一般類型的任務，並最小化特定工具。很明顯，我們要示範工具使用，以展示具體技術，但請注意我們不一定推薦這些工具為最佳或唯一辦法：大多數情況下其實有其他方法，但我們希望為你提供一個清晰的工作方法論。

學習途徑
----

在使用文章所述的工具前，你應該確實理解 HTML、CSS、JavaScript 核心語言的基本。比方說，在你開始處理複雜的程式碼錯誤前，要知道這些語言的基本原理、如何活用 JavaScript 函式庫、或是使用 test runner 給你的程式碼寫測試……等等。

最少，你需要扎實的基礎。

模組
--

現實世界的網路開發工具（TBD）

在此模組，我們會探索許多可用的網路開發工具。這包括檢查想解決的最常見任務類型，它們如何合併到工作流程中，以及目前可用於執行這些任務的最佳工具。

跨瀏覽器測試

此模組專注於測試網路專案的跨瀏覽器領域。在此，我們會辨認你的目標閱聽者（例如你最該對什麼樣的用戶、瀏覽器、還有設備操心？）如何做測試、不同類型的程式碼會碰上的主要問題、如何解決/減輕這些問題、哪些工具最能幫你測試和修復問題、還有如何用自動化加速測試。


網站表單-與數據合作 - 學習該如何開發 Web

網站表單-與數據合作
==========

這篇指南提供了一系列的文章，幫你掌握 HTML 表單的基本知識。對於與使用者互動，網站表單是一項十分有力的工具，最常使用於用戶數據蒐集，或控制使用者介面。但由於一些歷史與技術上的因素，並沒有顯著的方法發揮表單的潛力。在下面的指引中，我們將介紹網站表單所有基本面向，包括標記他們的 HTML 結構、設定控制器樣式、驗證數據及將數距提送至伺服器

參考文章列表
------

1. 我的第一個 HTML 表單 (en-US)
2. 如何構建 HTML 表單 (en-US)
3. 本機表單控件 (en-US)
4. CSS 和 HTML 表單
    1. 造型 HTML 表單 (en-US)
    2. HTML 表單高級造型 (en-US)
    3. 表單控件屬性兼容表 (en-US)
5. 發送和檢索表單數據 (en-US)
6. 數據表單驗證 (en-US)
7. 如何創建自定義表單控件 (en-US)
8. 通過 JavaScript 發送形式 (en-US)
    1. 使用 FORMDATA 對象
9. 在傳統的瀏覽器的 HTML 表單 (en-US)
HTML 文件
-------

### HTML 元素

| HTML 元素 | 元素的 DOM interface | 說明 |
| --- | --- | --- |
| `<button>` (en-US) | `HTMLButtonElement` (en-US) | 該`按鈕`元素表示一個可點擊的按鈕。 |
| `<datalist>` (en-US) | `HTMLDataListElement` (en-US) | 該數據列表元素包含了一組 `<option>` (en-US) 表示對其他表單元素的值可能的選擇要素。 |
| `<fieldset>` (en-US) | `HTMLFieldSetElement` (en-US) | 該字段集是用來在表單中的組數表單元素。 |
| `<form>` (en-US) | `HTMLFormElement` (en-US) | 的`形式`元素表示的文件的一部分，它包含使用戶能夠提交信息給 web 服務器的交互元件。 |
| `<input>` (en-US) | `HTMLInputElement` (en-US) | 該 `輸入`元素用於創建表格的交互式控制。 |
| `<label>` (en-US) | `HTMLLabelElement` (en-US) | 該`標籤`元素代表一個項目在用戶界面的標題 |
| `<legend>` (en-US) | `HTMLLegendElement` (en-US) | 在`傳說`元素代表一個標題為其父 `<fieldset>` (en-US) 的內容。 |
| `<meter>` (en-US) | `HTMLMeterElement` (en-US) | 所述`米`元素表示一個已知的範圍內的任一標量值或分數值。 |
| `<optgroup>` (en-US) | `HTMLOptGroupElement` (en-US) | 在 `OPTGROUP` 元素創建一個 `<select>` (en-US) 元素中的一組選項。 |
| `<option>` (en-US) | `HTMLOptionElement` (en-US) | 在 HTML `選項`元素用於創建表示 `<select>` (en-US) ，一個 `<optgroup>` (en-US) 或 `<datalist>` (en-US) 元素中的項目的控制。 |
| `<output>` (en-US) | `HTMLOutputElement` (en-US) | 的`輸出`元素表示一個計算的結果。 |
| `<progress>` (en-US) | `HTMLProgressElement` (en-US) | 的`進展`元素用於查看任務的完成進度。 |
| `<select>` (en-US) | `HTMLSelectElement` (en-US) | 在`選擇`元素代表呈現一個選項菜單的控制。 |
| `<textarea>` (en-US) | `HTMLTextAreaElement` (en-US) | 該 `textarea` 的元素代表多行純文本編輯控制。 |

**備註：** 所有的表單元素，因為所有的 HTML 元素，支持 `HTMLElement` (en-US) DOM 接口。

### HTML 屬性

| 屬性 | 能使用該屬性的 HTML 元素 | 說明 |
| --- | --- | --- |
| accept | `<form>` (en-US), `<input>` (en-US) | 的類型列表服務器接受，通常是文件類型。 |
| accept-charset | `<form>` (en-US) | 支持的字符集列表。 |
| action | `<form>` (en-US) | 一個程序處理通過表單提交的信息的URI。 |
| autocomplete | `<form>` (en-US), `<input>` (en-US) | 指示是否在這個表單控件可以在默認情況下有其值由瀏覽器自動完成。 |
| autofocus | `<button>` (en-US)、
 `<input>` (en-US)、
 `<select>` (en-US)、
 `<textarea>` (en-US) | 該元素應該在頁面加載後自動聚焦。 |
| checked | `<input>` (en-US) | 指示是否應將元素在頁面加載檢查。 |
| cols | `<textarea>` (en-US) | 限定在一個textarea的列數。 |
| data | `<object>` (en-US) | 指定的資源的URL。 |
| dirname | `<input>` (en-US),
 `<textarea>` (en-US) |  |
| disabled | `<button>` (en-US)、`<fieldset>` (en-US)、`<input>` (en-US)、`<optgroup>` (en-US)、`<option>` (en-US)、`<select>` (en-US)、`<textarea>` (en-US) | 表明用戶是否可以與元件進行交互。 |
| enctype | `<form>` (en-US) | 定義當表單數據的內容類型`的方法`是POST。 |
| for | `<label>` (en-US)、`<output>` (en-US) | 描述了屬於這一種元素。 |
| form | `<button>` (en-US)、`<fieldset>` (en-US)、`<input>` (en-US)、`<label>` (en-US)、`<meter>` (en-US)、`<object>` (en-US)、`<output>` (en-US)、`<progress>` (en-US)、`<select>` (en-US)、`<textarea>` (en-US) | 表明是元件的所有者的形式。 |
| high | `<meter>` (en-US) | 表示下界的上限範圍。 |
| list | `<input>` (en-US) | 標識的預定義的選項的列表，以向用戶建議。 |
| low | `<meter>` (en-US) | 指示上限較低的範圍內。 |
| max | `<input>` (en-US)、`<meter>` (en-US)、`<progress>` (en-US) | 指示所允許的最大值。 |
| maxlength | `<input>` (en-US) 、
 `<textarea>` (en-US) | 定義了在元件允許的字符的最大數目。 |
| method | `<form>` (en-US) | 定義提交表單時使用的HTTP方法。可GET（默認）或POST。 |
| min | `<input>` (en-US) 、
 `<meter>` (en-US) | 指示所允許的最小值。 |
| multiple | `<input>` (en-US)、
 `<select>` (en-US) | 表示是否多個值所用的類型的輸入可以輸入`電子郵件`或`文件`。 |
| name | `<button>` (en-US)、`<form>` (en-US)、`<fieldset>` (en-US)、`<input>` (en-US)、`<output>` (en-US)、`<select>` (en-US)、`<textarea>` (en-US) | 該元素的名稱。例如所使用的服務器，以確定在表單提交的字段。 |
| novalidate | `<form>` (en-US) | 此屬性表明，當提交表單應該無法通過驗證。 |
| optimum | `<meter>` (en-US) | 表示最佳數值。 |
| pattern | `<input>` (en-US) | 定義一個正則表達式元素的值將針對驗證。 |
| placeholder | `<input>` (en-US)、
 `<textarea>` (en-US) | 提供一個提示什麼可以在字段中輸入的用戶。 |
| readonly | `<input>` (en-US) 、
 `<textarea>` (en-US) | 指示該元素是否可以編輯或沒有。 |
| required | `<input>` (en-US) 、
 `<select>` (en-US)、
 `<textarea>` (en-US) | 指示此元素是否必填。 |
| rows | `<textarea>` (en-US) | 限定在一個textarea的行數。 |
| selected | `<option>` (en-US) | 定義了將在頁面加載所選的值。 |
| size | `<input>` (en-US)、
 `<select>` (en-US) | 限定了元件的寬度（以像素為單位）。如果該元素的`類型`的屬性是`文本`或`密碼`那麼它的字符數。 |
| src | `<img>` (en-US) | 可嵌入內容的URL。 |
| step | `<input>` (en-US) |  |
| target | `<form>` (en-US) |  |
| type | `<button>` (en-US) 、
 `<input>` (en-US) | 限定了元件的類型。 |
| usemap | `<img>` (en-US) |  |
| value | `<button>` (en-US)、
 `<option>` (en-US)、
 `<input>` (en-US)、
 `<meter>` (en-US)、
 `<progress>` (en-US) | 定義了將被顯示在頁面上的負載元件的默認值。 |
| wrap | `<textarea>` (en-US) | 指示文本是否應被包裹或沒有。 |

### 規範性引用文件

* W3C HTML 5.1 規範（表格）
* WHATWG HTML 生活水平（表格）


JavaScript — 動態的客戶端指令 - 學習該如何開發 Web

JavaScript — 動態的客戶端指令
=====================

JavaScript 程式語言可讓你在網頁上建構複雜的事物。當網頁不僅僅呆板呈現給你靜態的內容（像是即時的內容更新，互動式地圖、2D/3D 動畫、滑鼠操控影片播放…等等），你可以大膽猜測 JavaScript 已經參與其中。

學習途徑
----

JavaScript 相較於 HTML 和 CSS 這些技術可以說比較困難。開始嘗試學習 JavaScript 之前，強烈建議你起碼先熟悉上述兩項技術，或者了解其它的更好。可以透過以下單元開始：

* 入門認識 Web
* HTML 簡介
* CSS 簡介

若你之前有其他程式語言的撰寫經驗，也許會有幫助。

當熟悉 JavaScript 的基本知識之後，你應該進入一些更進階的主題，像是：

* 深入 JavaScript，像是 JavaScript 指南
* Web API
單元
--

本主題涵蓋許多單元，建議你依下列順序閱讀。

JavaScript 初探

在我們的第一個 JavaScript 單元，在帶你初次實際撰寫 JavaScript 程式之前，我們先回答幾個基本的問題，像是「什麼是 JavaScript？」、「它看起來是什麼樣子？」、「它能做些什麼？」。接著，我們深入地討論幾個 JavaScript 關鍵的組成元素，例如：變數、字串、數字、陣列。

JavaScript 構成元素

在這個單元，我們繼續含蓋 JavaScript 關鍵的基本元素，把焦點放在常見程式碼區塊的類型，像是條件陳述式、迴圈、函數以及事件。你已經在這個課程中看過這些東西，但只是匆匆一瞥，在這裡我們會明確地討論。

JavaScript 物件介紹

在 JavaScript 程式語言，絕大部分的東西都是物件，從核心的 JavaScript 元素像是字串（string）和陣列（array）到基於 JavaScript 建構的瀏覽器 API 都是。你甚至可以建立自己的物件，將相關的變數與函數封裝成能有效率操作的集合體。如果你想更深入了解這門程式語言的知識，並撰寫出更有效率的程式碼，了解 JavaScript 物件導向的本質是重要的，因此我們準備這個單元來幫助你。這裡我們教詳細的物件理論與語法，看看要如何建自你自己的物件，以及說明什麼是 JSON 資料和怎麼使用它。

非同步的 JavaScript

這個單元我們來討論非同步的 JavaScript，它為什麼重要，以及它能如何有效處理像是由伺服器抓取資料這種阻塞性操作（它會造成網頁停頓）。

用戶端的 web API

當你走在用 JavaScript 撰寫用戶端程式，來建構網站或應用程式的路上，不利用 API 很難走很遠，介接在操控瀏覽器、作業系統的不同功能，或是接收來自其它網站、服務的資料。在這個單元中，我們將討索什麼是 API ，以及如何使用幾個在你開發過程中，十分頻繁被使用到的 API 。

解決常見的 JavaScript 問題
-------------------

在你寫網頁時，可參閱〈透過 JavaScript 解決常見的問題〉內所提供的連結，解決許多常見問題。

參考資源
----

JavaScript on MDN

MDN 上連結到各篇 JavaScript 核心文件的主要，在這裡你可以找到關於 JavaScript 程式語言各方面廣泛的參考文件，還有一些進階的指引幫助你成為熟練的 JavaScript 使用者。

Learn JavaScript

對於想成為網站開發者一個很好的資源，以互動的方式學習 JavaScript ，包含短課程、互動測驗，自動評估狀況給予指引。前 40 堂課是免費，完整的課程可以在一次付費買下。

JavaScript Fundamentals on EXLskills

在免費的 EXLskills 開源課程中，介紹給你所有開始建構 JavaScript 應用程式所需要的東西。

Coding math

一系列優質的教學影片，教你需要了解哪些數學知識，來讓你成為有效率的程式設計師。（作者：Keith Peters）


學習 HTML ：指南與教學 - 學習該如何開發 Web

學習 HTML ：指南與教學
==============

為了建立網頁，你應該要先知道 HTML——用來建造網站架構的科技。 HTML 是用來辨認網頁中的內容該如何被解讀，例如說被解讀為：一個段落（paragraph）、清單（list）、文件標題（heading）、連結（link）、圖片（images）、多媒體播放器（multimedia player）、表單（form）或是任何一個可使用的「元素（elements）」，甚至是你自己定義的新元素。

學習途徑
----

理想上，你應該從學習 HTML 開始你的學習旅程。可以先從閱讀 HTML 介紹 開始。接下來你可以開始閱讀以下的進階主題：

* CSS 及如何使用它來美化 HTML （例如改變文字大小和字形、加上邊框與陰影、用多欄位[columns]來排版你的頁面、增加動畫和視覺效果……）
* JavaScript 及如何使用它來為網頁增加互動性的功能（例如將你的位置顯示在地圖上、點擊按鈕讓 UI 上的元素出現或消失、將用戶的一些資料存放在他們的電腦上……等等）

當你開始閱讀這主題時，你至少必須對使用電腦有基礎了解，以及會基本的上網（諸如網頁瀏覽、了解網頁內容）。而你需要建立一個已安裝基本軟體（詳細軟體請參閱安裝基本軟體）的基礎工作環境，並且了解如何建立與管理檔案（詳細請參閱檔案處理）——這些都包含在新手 Web 入門的章節裡。

建議你在開始學習 HTML 這個項目之前，可以先從網際網路開始瞭解是如何運作的。儘管知道網路的運作不是必要的；大部分的項目都在 HTML 基礎 的文章中 HTML 介紹這個章節更詳盡地介紹模組（module）、albeit。

模組
--

這主題包含了以下幾個單元, 你可以根據以下順序來閱讀他們。強烈推薦從第一個單元開始讀起。

HTML 介紹

這個單元為你提供一個平台，讓你熟悉重要的概念和語法、思考如何將 HTML 應用於文本、如何創建超連結以及使用 HTML 來構建網頁。

嵌入多媒體

本單元探索如何在你的網頁中使用 HTML 嵌入多媒體，包括置入圖片的各種方法，以及如何嵌入影片，音檔甚至其它網頁。

表格

以易於理解、無障礙的方式在網頁顯示表格數據可能是一個挑戰。此單元涵蓋基本的表格標記以及更複雜的功能，例如實行標題和摘要。

解決常見的 HTML 問題
-------------

利用 HTML 解決常見問題提供部分連結，這些內容解釋了在創建網頁時如何使用 HTML 解決常見的問題：標題、添加圖片或影片、強調內容、創建基本表單等等。

或許你還想看
------

網站表單

這篇指南提供一系列的文章，幫助你掌握 HTML 表單的基本知識。對於與使用者互動，網站表單是十分有力的工具，最常使用於用戶資料蒐集，或控制使用者介面。但由於一些歷史與技術上的因素，並沒有顯著的方法發揮表單的潛力。在下面的指引中，我們將介紹網站表單所有基本面向，包括標記他們的 HTML 結構、設定控制器樣式、資料驗證及將資料傳送至伺服器。

HTML

MDN 的 HTML 參考文件的主要入口，包括詳細的元素和屬性參考-例如，如果你想知道元素具有哪些屬性或屬性具有什麼值，那麼這是一個很好的起點。


CSS（樣式表） - 學習該如何開發 Web

CSS（樣式表）
========

階層式樣式表（CSS）是學習完 HTML 之後，你應該學習的第一項技術。HTML 用於定義內容的架構與語意，CSS 則是用來設定樣式與佈局方式。舉例來說，你可以使用 CSS 來改變內容的字體、顏色、字型大小、間距、拆分成多欄，或是加入動畫和其他裝飾性質的特性。

### 想要成為 Web 前端開發人員？

我們整理了一門課程，包含了你實現目標需要的所有基礎知識。

開始 (en-US)

先備知識
----

在嘗試 CSS 之前，你應該先了解基本的 HTML 知識。我們建議先閱讀 HTML 介紹單元。在這個單元你會學習到關於：

* CSS，由 CSS 介紹單元開始
* 更進階 HTML 模組
* JavaScript 以及它如何在網頁加上動態的功能

在你了解最基礎的 HTML 運作思維後，我們推薦你同時學習 HTML 與 CSS，使兩者之間互相搭配。因為 HTML 搭配上 CSS 會變得無比有趣，兩者是密不可分的，你無法在不理解 HTML 的情況下獨立學習 CSS。

在開始這個主題之前，你應該要有電腦的基礎使用概念以及使用網頁的經驗（單純地瀏覽、查看內容）。你應該要有一個已經設定的好的基本工作環境，如同安裝基本軟體所敘述的，知道怎麼建立與管理檔案，如同處理檔案提到的內容。這兩者都是 Web 入門裡初學者單元中一部分。

建議你在開始課程前先閱讀 Web 入門，不過並非絕對必要，儘量那裡有許多詳細的介紹，大部分 CSS 概念在我們的 CSS 入門單元中也會含蓋到。

單元
--

這個主題按建議的學習順序包含以下的單元。強烈建議你從第一項開始。

CSS 入門

CSS（階層式樣式表）用來設定網頁的樣式及佈局，例如：改變文字的字體、顏色、大小及間距以及拆分為多欄，或是增加動畫或裝飾性的效果。這個單元提供一個溫和的路徑，讓你逐漸熟悉 CSS 的基礎概念，包含它的運作方式，語法是什麼樣子，以及如何開始在 HTML 裡添加樣式。

CSS 的組成 (en-US)

這個單元接續在 CSS 入門之後，現在已經熟悉了這門語言的語法，並有了一些基本的使用經驗，是時候再深入一些。這個單元關注於疊加（cascade）和繼承（inheritance）規則、所有可用的選擇器類型、單位、尺寸、背景與邊框的樣式、除錯，以及其它更多的。這裡的目的是在進入更進階的主題，像是文字樣式及 CSS 佈局之前，給你一個足以寫出合格 CSS 的工具包並幫助你了解所有的基礎理論。

裝飾文字

在含蓋了 CSS 語言基本的部分之後，下一個帶給你的 CSS 主題會專注於文字樣式的裝飾上，你將最常用 CSS 作的事情之一。在這裡，我們文字樣式的基礎，包括設定字體、粗細、斜體、行距與字距、陰影與其它的文字效果。整個單元圍繞於在你的頁面上套用選擇的字體，以及對清單和連結進行樣式調整。

CSS 的布局

到了這邊，我們已經看過了 CSS 的基礎知識，如何裝飾文字，如何裝飾並控制你內容所在的區。現在是時候來看看如合將你的這些區塊擺放到正確的位置，並能依不同的可視空間進行調整。我們已經含蓋了必須的先備知識，所以我們現在可以深入到 CSS 的布局，看看不同的顯示設定，像是新的佈局工具 flexbox 、 CSS grid 和定位（position）以及一些你可能仍想要了解的早期技術。

解決常見的 CSS 問題
------------

使用 CSS 解決常見的問題裡提供了許多單元的連結，其內容說明如何使用 CSS 解決在建立網頁時常見的問題。

在一開始，你主要將顏色套用到 HTML 元素或是背景；改變元素的大小、形狀和位置，然後添加、定義元素的邊框。當你對 CSS 的基礎知識有深刻的理解，就沒有太多作不到的事情。學習 CSS 其中一項最棒的事情，是當你了解了基本原理，通常你就能很好的抓到「什麼能作」、「什麼作不到」的感覺，既使是在你還不確切的知道要怎麼實現它的狀況下。

怪異的 CSS
-------

CSS 與你將遇到程式語言或設計工具在運作上有點不太一樣。為什麼要用這種方式運作？在下面影片中， Miriam Suzanne 解釋為什麼 CSS 是這樣運作，以及為什麼會這樣子發展。（可以利用字幕翻譯功能，將 CC 字幕轉為中文）

相關資源
----

MDN 中的 CSS 資源

在 MDN 網站裡，CSS 文件的主要入口，你將可以在這裡找到所有 CSS 語言的所有特性，以及它們詳細的參考資訊。想要知道一個屬性可以套用的所有設定嗎？這是一個不錯的地方。


Web 入門 - 學習該如何開發 Web

Web 入門
======

*Web 入門*是一系列簡潔的文章，介紹網頁開發的實用範例。你將運用相關工具建構簡易網頁並發布自己的程式碼。

替你的第一個網站說故事
-----------

建立個人網站需要很多功夫。如果你才剛開始接觸網頁設計，我們建議大家可以先從小地方著手。不是要你立刻就寫出跟「Facebook」一樣規模的網站，但自己架一個上線的網站一點都不難，現在就開始吧！

只要依序看過以下的系列文章，你將初學者蛻變成會架設自己的第一個上線網頁，Let's go！

安裝基本軟體

現有許多工具可建構網站。如果你剛起步，你可能不知從何選擇程式碼編輯器、框架、測試工具等等。我們將透過〈安裝基本軟體〉逐步引領你安裝基本的網頁開發軟體。

你的網站看起來會是什麼樣子？

在開始為自己的網站寫程式碼之前，你應該先規劃要呈現哪些資訊？要採用哪種字體與顏色？你可依照〈你的網站看起來會是什麼樣子？〉所提供的簡易方法，照著來規劃網站的內容與設計。

與各式各樣檔案打交道

一個網站包含許多檔案：文字內容、程式碼、樣式表、多媒體內容等等。當建立網站時，你需要將這些檔案組合成清晰的架構，並確保它們能彼此互動溝通。〈與各式各樣檔案打交道〉將引領你安排合理的檔案架構，以及你應該注意的問題。

HTML 基本概念

超文字標籤語言（Hypertext Markup Language，HTML）可用以建構網頁內容，並賦予其含意和用途。例如某段內容要分為多個段落，或是用項目符號列成幾個重點？要在網頁插入圖片？這裡需要以資料表格整理嗎？如果這些沒有嚇到你，〈HTML 基本概念〉將提供足夠的資訊。

CSS 基本概念

階層樣式表（Cascading Stylesheets，CSS）可用以塑造網站的特殊風格。例如這段文字要用一般的黑色，或是改用紅色標明重點？某段重要內容應該置於畫面的何處？想用什麼背景圖片及顏色裝飾你的網站？〈CSS 基本概念〉帶你入門。

JavaScript 基本概念

程式設計語言 JavaScript 可為你的網站增加互動功能，例如動畫、遊戲、按下按鈕的後續動作、將資料輸入表單、動態套用樣式的效果等等。〈JavaScript 基本概念〉將帶你瞭解此一有趣的程式語言及其能耐，並讓你快速入門。

將你的網站發佈上線

在寫完程式碼並整理好檔案之後，接著就是將網站發佈上線，讓其他人可以瀏覽、欣賞內容。〈將你的網站發佈上線〉將帶領你以最輕鬆的方法發佈你的範例程式碼。

網站的運作方式

在瀏覽喜愛的網站時，你可能未意識到瀏覽器正於背景中運作著許多複雜事情。〈網站的運作方式〉將簡略說明網頁瀏覽時所發生的大小事。


Multimedia and Embedding - 學習該如何開發 Web

Multimedia and Embedding
========================

到目前為止，我們已經看到了很多文字，但是只使用文字讓人感到無聊。讓我們開始研究如何透過更有趣的內容讓網絡變得活躍起來！本單元探討如何使用 HTML 在你的網頁中包增加媒體，包括可以嵌入圖像的不同方式，以及如何嵌入影片，音訊甚至整個網頁。

預備知識
----

在此單元開始之前，我們假設你對 HTML 基礎知識 (如HTML 介紹) 已經有一定的了解，如果還沒有，建議你先預習該部分再回來。

**備註：** 如果你所操作的電腦、平板或裝置環境不允許你建立自己的檔案，你可以在諸如 JSBin 或 Glitch 這樣的網站上嘗試(多數的)範例程式碼。

導覽
--

本單元包含以下章節，它們將帶你了解在網頁上嵌入多媒體的所有基礎知識。

HTML 中的圖片

可以考慮到的多媒體種類很多，但是從用以將簡單圖像嵌入網頁中不起眼的 img元素開始是很合乎邏輯的。在本文中，我們將研究如何更深入地使用它，包括基礎知識，使用`<figure>` (en-US)加上標題的註釋以及它與 CSS 背景圖像的關係。

視訊與音訊內容 (en-US)

接著，我們將研究如何使用 HTML5 `<video>` (en-US)和`<audio>` (en-US) 元素在頁面上嵌入視訊和音訊，包括基本知識，以提供對不同頁面的訪問文件格式添加到不同的瀏覽器，添加標題和字幕，以及如何為舊版瀏覽器添加後備廣告。

從物件到 iframe — 其他嵌入技巧 (en-US)

在這裡，我們想橫跨一步，著眼於幾個元素，這些元素可以使你將各種內容類型嵌入到網頁中：`<iframe>` (en-US)，`<embed>` (en-US)和 `<object>` (en-US)元素。 <iframe>用於嵌入其他網頁，另外兩個允許你嵌入 PDF，SVG 甚至 Flash（一種即將消逝的技術，但你可能仍會定期看到它）。

為 Web 新增向量圖 (en-US)

向量圖形在某些情況下可能非常有用。 與 PNG / JPG 等常見格式不同，它們在放大時不會失真/像素化-在縮放時可以保持平滑。 本文向你介紹什麼是向量圖，以及如何在網頁中加入流行的SVG格式。

適應性圖片 (en-US)

在本文中，我們將學習適應性圖片 (又稱響應式圖片)的概念。適應性圖片在不同螢幕尺寸，解析度和其他類似功能差異很大的設備上都能很好地運作。我們還會研究 HTML 提供了哪些工具來幫助實現它們。 這有助於提高不同設備之間的性能。 響應式圖片只是響應式設計的一部分，在將來你學習 CSS 的單元中還會有響應式圖片的單元。

評量
--

以下評量中將測試你對以上指南中介紹的 HTML 基礎的理解：

Mozilla 啟動頁面 (en-US)

在此測驗中，我們將測試你對本區塊文章中討論的一些技術的了解，使你能夠向時髦的啟動頁面添加有關 Mozilla 的一些圖片和視訊！

另見
--

增加點擊映射到圖片上層 (en-US)

圖像映射提供了一種機制，可以使圖像的不同部分鏈接到不同的位置。（請試想在地圖上點擊每個不同國家/地區以取得更多資訊）此技術有時很有用。

網頁知識基礎 2

一個出色的 Mozilla 基礎課程，探索和測試此多媒體和嵌入單元中討論的一些技能。 深入研究網頁組成，可訪問性設計，共享資源，使用線上媒體和開放性工作的基礎知識（這意味著你的內容可以免費獲得併可以由他人共享）。


使用HTML解決日常問題 - 學習該如何開發 Web

使用HTML解決日常問題
============

以下連結會給出 HTML 常見待解問題的方法

### 基本結構

HTML 文件的最基本結構應用。如果你是 HTML 新手，就先從這裡開始看。

* 如何建立基本 HTML 文件
* 如何有邏輯地分割網頁 (en-US)
* 如何建立良好的標題段落結構
### 基本文字語法

HTML 專攻於為文件提供語義資訊，因此 HTML 可以提供使用者更精準的文件資訊傳達方式。

* 如何建立清單
* 如何強調文件的內容
* 如何表示出一段文字的重要性
* 如何顯示程式碼 (en-US)
* 如何為圖片加入註記
* 如何標示並註記縮寫 (en-US)
* 如何在網頁中加入引用 (en-US)
* 如何加入詞語的定義 (en-US)
### 超連結

超連結 (en-US)把 HTML 導覽變得相當容易，它可以這麼用：

* 如何建立超連結
* 如何用 HTML 建立表格內容
### 圖片與多媒體

* 如何把圖片加進網頁
* 如何把視訊內容加進網頁 (en-US)
* 如何把音訊內容加進網頁 (en-US)
### 腳本與樣式

HTML 只建立文件的基礎架構，可以透過 CSS 或腳本使內容呈現更具互動性。

* 如何在網頁中使用 CSS
* 如何在網頁中使用 JavaScript (en-US)
### 嵌入內容

* 如何在網頁中嵌入另一個網頁 (en-US)
* 如何在網頁中加入 FLASH 內容 (en-US)
不常見或進階的問題
---------

除了上述的基本功能外，HTML 還提供許多進階功能讓使用者解決較複雜的問題。這些文章可以幫助你處理一些較不常見的情況：

### 表單

表單是一種用來把網頁資料傳送到網路伺服器的複雜 HTML 結構。我們鼓勵你讀一遍我們對此的完整指南。你可以從以下文章開始：

* 如何建立簡單的表單 (en-US)
* 如何組織表單的架構
### 表格訊息

有些被稱為表格訊息的資訊需要被組織成擁有直行與橫列的表格。這是其中一種最複雜的 HTML 架構，要熟練它並不簡單：

* 如何建立資料試算表
* 如何讓 HTML 表格可被獲取
### 資料表示方式

* 如何用 HTML 表示數值——參見上標與下標 (en-US)及顯示電腦程式碼 (en-US)
* 如何使用資料屬性 (en-US)
### 進階文字語法

* 如何控制 HTML 換行
* 如何標記改變（新增與移除的文字）參見 `<ins>` (en-US) 及 `<del>` (en-US) 標籤
### 進階圖片 & 多媒體

* 如何在網頁中加入響應式圖片 (en-US)
* 如何在網頁中加入向量圖片 (en-US)
* 如何在圖片上加入圖像映射 (en-US)
### 國際化

HTML 不只支援單一語言，它還有提供工具來處理常見的國際化問題。

* 如何在單一網頁中加入多國語言
* 如何用 HTML 表示時間與日期 (en-US)
### 效能

* 如何創建快速載入 HTML 網頁 (en-US)


HTML 表格 - 學習該如何開發 Web

HTML 表格
=======

HTML 的常見任務就是建構表格資料，某些元素與屬性正是為此目的而生。HTML 以及用於樣式化的 CSS 能方便顯示諸如讀書計劃、附近游泳池的開放時間、分析最喜歡的恐龍或足球隊……之類的表格資訊。本模塊將帶你認識建構 HTML 表格資料所需的一切。

先決條件
----

開始本模塊之前，你要理解基本的 HTML：請參見 HTML 介紹。

**備註：** 如果你用的電腦或平板之類的設備，無法允許建立自己的檔案，你可以把大部分的例子放在線上程式網站，例如 JSBin 或 Glitch。

教學
--

本模塊包含以下文章：

HTML 表格基礎

這篇文章將介紹 HTML 表格，包含像是行列、標題、製作單元格、跨多行與列等基礎知識，還有如何把他們組合在一起，以方便樣式化。

HTML 表格進階與無障礙 (en-US)

本模塊的第二篇文章將介紹一些 HTML 表格的進階功能：例如說明、摘要、將行分成標頭、身體、還有註腳三大部分。另外，我們也會探討針對視障人士的表格無障礙。

評估
--

建構行星數據 (en-US)

在我們的表格評估中，我們將提供太陽系中行星的一些數據，並讓你把他們構建到 HTML 表格中。


HTML介紹 - 學習該如何開發 Web

HTML介紹
======

本質上，HTML 是一種非常簡單的語言，由元素所組成。元素可以賦予文字片段不同的意義 (比方說，將它們描述成段落、項目清單，或是表格的一部分)、將文件組織成不同的邏輯區段 (如標頭(header)、三行的內文，或是導覽目錄)，以及在網頁中嵌入圖片或影片等內容。在這個主題中我們將介紹前面兩項，並介紹基本概念以及語法以讓你了解 HTML。

預備知識
----

在開始閱讀之前，你並不需要具備任何 HTML 知識，你只要能夠操作電腦、瀏覽網頁並消化其中的內容即可。你需要建立一個基礎工作環境，並且了解如何建立與管理檔案── 這些都屬於我們 Web 入門 的一部分。

**備註：** 如果你是在某些無法建立個人檔案的電腦/平板/其他裝置上進行，你可以在一些線上 coding program（如 JSBin 或 Glitch）上測試程式碼範例。

導覽
--

這個主題包含以下子題，將帶你了解所有 HTML 的基礎理論，並且提供充足的機會讓你測試所習得的技能。

HTML 入門

包含 HTML 最基礎的部分 ── 我們將定義元素（elements）、屬性（attributes）以及其他重要術語，並且介紹它們的使用方法。除此之外，我們也將說明典型的 HTML 網頁及其中的元素是如何構成的，並解釋其他重要的基本語言特性。還有，我們也會玩一些 HTML，好引發你的興趣！

在 head 中有什麼? HTML 中的後設資料(Metadata)

HTML 文件的 head 是在網頁加載完畢之後，不會顯示在瀏覽器上的部分。其中包含一些資訊，如頁面的標題(`<title>`)、CSS 的連結 (當你想利用 CSS 來妝點你的頁面 HTML 時，你會用到它們)、網頁圖示(favicon)的連結，以及 metadata (裡頭承載了有關於該 HTML 的資料，如作者、描述該文件的關鍵詞等。)

HTML 文字的基礎知識

一個 HTML 的主要作用是賦予純文字意義(又稱為語義化 (en-US))，好讓瀏覽器知道如何正確地顯示它。這篇文章將探討如何使用 HTML 來將文字區塊拆解為標題(heading)和段落(paragraph)、強調字詞、建立列表等等。

建立超連結

超連結真的非常重要 — 它造就了我們現今所知的網路。這篇文章介紹超連結的使用語法，並且探討建立連結的最佳實踐方法。

進階文字格式 (en-US)

在 HTML 中還有許多可以用來格式化文字的元素，但我們沒有在 HTML 文字的基礎知識中提及這些內容。雖然這些元素比較鮮為人知，不過還是相當值得一談。在這篇文章中，你將會學到如何表示引言、描述列表、程式碼、上下標，及聯繫訊息等等。

文件與網站架構

除了分別定義網頁的各個成分（例如：段落或是圖片），HTML 還能定義網頁上的區塊（例如：標頭、導航列或是主要內容）。這篇文章將介紹如何規劃一個基本的網頁架構，以及如何透過編寫 HTML 來表示網頁架構。

HTML 除錯 (en-US)

如果 HTML 出錯了，卻找不到哪裡有錯誤該怎麼辦？這篇文章將會介紹一些能幫得上忙的實用工具。

評量
--

下面的評量將測試你對於以上的 HTML 基礎是否已經了解。

標記信件內容 (en-US)

我們都學過怎麼寫信，而信件也是用來測試我們格式化文字技巧的好例子。在這份測驗中，你將需要以 HTML 將一封信標記成題目要求的樣子。

組織網頁內容 (en-US)

這份測驗將要測試你利用 HTML 來組織網頁的能力，該網頁將包含頁眉(header)、頁腳(footer)、導覽列(navigation)、內文(main content)和側邊攔(sidebar)。

另見
--

Web literacy basics 1

Mozilla 基金會所提供的一個優質課程。該課程探索並測驗了很多在本主題中所提及的技術。透過裡頭的六大學習主題，學習者能夠熟悉閱讀、撰寫以及參與網路，並經由實作與合作了解網路基礎。