Skip to main content
快速入門:新增 HTML 控制項和處理事件 (HTML)

Applies to Windows and Windows Phone

每個應用程式都需要控制項,例如按鈕、 核取方塊以及下拉式清單。 使用 JavaScript 的 Windows 執行階段應用程式可以使用兩種類型的控制項:內建 HTML 控制項和適用於 JavaScript 的 Windows Library 控制項。內建 HTML 控制項是 HTML 標準的一部分,例如按鈕和核取方塊。

這裡我們將重點放在如何建立和使用 HTML 控制項。下一個主題 快速入門:新增 WinJS 控制項與樣式將說明如何建立和使用 WinJS 控制項。

(僅限 Windows) 如需了解此功能的運作情形,請參閱 應用程式功能,從開始到完成系列:   使用者互動:觸控輸入...等等以及 Windows 市集應用程式 UI,從開始到完成

先決條件

什麼是控制項?

在許多應用程式開發模型中,您需要控制項才能顯示內容或是與內容互動。由於大部分 HTML 元素都能顯示內容並且回應各種不同的事件,因此對於使用 JavaScript 的 Windows 執行階段應用程式而言,控制項與元素之間的分別並不是那麼明確。我們所謂的元素和物件,其主要目的在於提供如同控制項的互動性。 如需屬於這個類別的元素和物件清單,請參閱 依功能分類的控制項

新增 HTML 控制項

您可以在使用 JavaScript 的 Windows 執行階段應用程式中使用任何 HTML 控制項。

Hh465402.wedge(zh-tw,WIN.10).gif 新增 HTML 控制項

  • 若要新增 HTML 控制項,只需將控制項的 HTML 新增到您的頁面,就像製作一般網頁一樣。這個範例建立一個 button
    <button id="button1">An HTML Button</button>

    建議您為控制項指定一個識別碼或類別名稱,如此一來,您就可以輕鬆抓取和操作該控制項。本文稍後說明如何附加事件時,您將會使用按鈕的識別碼尋找按鈕。

控制項的 HTML 不一定像按鈕一樣單純。例如,若要建立 slider 控制項,您要使用 input 輸入元素:

<input type="range" />

如需可用 HTML 控制項的清單以及用來建立控制項的標記,請參閱 控制項清單

處理事件

每一個控制項都會提供讓您回應使用者動作的事件。例如,按鈕控制項提供使用者按一下按鈕時引發的 click 事件。您會建立稱為事件處理常式的函式來處理事件,然後向控制項登錄事件處理常式。

登錄事件處理常式的方式有兩種。一種方式是將控制項的事件屬性設定為 JavaScript 事件處理常式或 JavaScript 陳述式的名稱,藉此在 HTML 中新增事件處理常式。如需關於這種方式的詳細資訊,請參閱為什麼不應該在標記中設定事件處理常式一節。

另一種是透過程式設計的方式新增事件處理常式。我們建議您採用這種方式。

Hh465402.wedge(zh-tw,WIN.10).gif以程式設計的方式登錄事件處理常式

  1. 建立控制項並指派其識別碼。這個範例會建立一個按鈕,並且指定 "button1" 做為其識別碼。
    <button id="button1">An HTML button</button>
  2. 僅針對這個範例建立 Paragraph 元素,並且指定 "button1Output" 做為其識別碼。您將使用這個元素顯示關於按鈕 Click 事件的資訊。

    <p id="button1Output"></p>
  3. 在您的 JavaScript 程式碼中定義事件處理常式。多數的事件處理常式只會接受一個引數,即是包含事件資訊的 Event 物件。其他事件可能會傳回其他類型的事件資訊物件,提供專屬於該事件的資訊。

    click 事件提供了包含該事件資訊的 MouseEvent 物件,例如,按下哪一個滑鼠按鈕,以及哪一個物件引發事件。 這個範例建立了一個 click 事件處理常式,使用 MouseEvent 物件來獲得使用者按到 X 和 Y 軸的點座標。

    ( click 事件也會對觸控和鍵盤做出互動回應。這個主題的範例假設使用者是用滑鼠來作按鈕輸入。如需與觸控和不同裝置互動的詳細資訊,請參閱 回應使用者互動)。

    function button1Click(mouseEvent) {
        var button1Output = document.getElementById("button1Output");
        button1Output.innerText =
        mouseEvent.type
        + ": (" + mouseEvent.clientX + "," + mouseEvent.clientY + ")";
    
    }
  4. 現在您需要將事件附加到控制項,方法是抓取事件並呼叫 addEventListener。問題是,您何時必須抓取控制項?您可以把它新增到 JavaScript 程式碼的任何位置,但接著在控制項存在之前,可能會有一個機會呼叫它。

    • 如果您將控制項新增到由 default.html 與 default.js 定義的應用程式起始頁,請使用 WinJS.UI.processAll 函式登錄事件處理常式。 每個 Microsoft Visual Studio 範本都會建立 default.js 檔案,該檔案會呼叫 activated 事件處理常式中的 WinJS.UI.processAll。 因為這是非同步方法,所以 WinJS.UI.processAll 方法會傳回 Promise。若要附加您的事件處理常式,請針對 WinJS.UI.processAll 傳回的 Promise 提供 then done 函式,並且使用該函式附加您的事件處理常式 (如需 Promise 的詳細資訊,請參閱 JavaScript 的非同步程式設計)。

      這個範例使用 WinJS.UI.processAll 附加按鈕的事件處理常式。

      (function () {
          "use strict";
      
          var app = WinJS.Application;
          var activation = Windows.ApplicationModel.Activation;
          WinJS.strictProcessing();
      
          app.onactivated = function (args) {
              if (args.detail.kind === activation.ActivationKind.launch) {
                  if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                      // TODO: This application has been newly launched. Initialize
                      // your application here.
                  } else {
                      // TODO: This application has been reactivated from suspension.
                      // Restore application state here.
                  }
                  args.setPromise(WinJS.UI.processAll().done(function () {
                      var button1 = document.getElementById("button1");
                      button1.addEventListener("click", button1Click, false);
                      })
                  );
              }
          };
      
          app.oncheckpoint = function (args) {
              // TODO: This application is about to be suspended. Save any state
              // that needs to persist across suspensions here. You might use the
              // WinJS.Application.sessionState object, which is automatically
              // saved and restored across suspension. If you need to complete an
              // asynchronous operation before your application is suspended, call
              // args.setPromise().
          };
      
          // The click event handler for button1
          function button1Click(mouseEvent) {
              var button1Output = document.getElementById("button1Output");
              button1Output.innerText =
                  mouseEvent.type
                  + ": (" + mouseEvent.clientX + "," + mouseEvent.clientY + ")";
      
          }
      
          app.start();
      })();
      

      如需 WinJS.UI.processAll 方法的詳細資訊,請參閱 快速入門:新增 WinJS 控制項與樣式

    • 如果您要將控制項新增到 頁面控制項,請使用 頁面控制項的 ready 函式附加事件處理常式。

      WinJS  頁面控制項提供將內容細分成可重複使用之模組單位的方式。視您用來建立應用程式的 Visual Studio 範本而定,您的應用程式可能自動包含一或多個頁面控制項。

      當您建立 頁面控制項時,它會自動包含可用來為按鈕新增事件處理常式的 ready 函式。這個範例顯示頁面控制項的完整 JavaScript 程式碼,該控制項會將 click 事件處理常式新增到按鈕。

      // home.js
      (function () {
          "use strict";
      
          WinJS.UI.Pages.define("/pages/home/home.html", {
              // This function is called whenever a user navigates to this page. It
              // populates the page elements with the app's data.
              ready: function (element, options) {
                  // TODO: Initialize the page here.
                  var button1 = element.querySelector("#button1");
                  button1.addEventListener("click", this.button1Click, false);
              },
      
              button1Click: function(mouseEvent) {
                  var button1Output = document.getElementById("button1Output");
                  button1Output.innerText =
                  mouseEvent.type
                  + ": (" + mouseEvent.clientX + "," + mouseEvent.clientY + ")";
      
              }
          });
      })();
      

      如需 頁面控制項的詳細資訊,請參閱 新增頁面控制項

    • 如果您要將控制項新增到自訂的 HTML 和 JavaScript 檔案中,請處理 DOMContentLoaded 事件,並使用這個事件來呼叫 WinJS.UI.processAll。您可以在程式碼中的任何位置登錄 DOMContentLoaded 事件,因為執行程式碼時 document 物件已存在。針對 WinJS.UI.processAll 傳回的 Promise 提供 then done 函式,並且使用該函式附加您的事件處理常式。

當您執行應用程式並按一下按鈕時,會顯示點選處的座標。

為什麼不應該在標記中設定事件處理常式

您可以在標記中新增事件處理常式,但有時因為範圍的問題,這樣做反而比使用 addEventListener 方法新增更加複雜。當您使用 Visual Studio 建立新的使用 JavaScript 的 Windows 執行階段應用程式 [空白的應用程式] 時,會建立這個 default.js 檔案:

(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    app.start();
})();

所有程式碼都會包裝在匿名的全域函式中。將程式碼包裝在匿名的全域函式中,是撰寫程式碼的好方法,因為這樣會限制程式碼的範圍,並且避免干擾全域命名空間。如果您新增之前所述的事件處理常式,程式碼後置檔案看起來會像這樣:

(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    function button1Click(mouseEvent) {
        var button1Output = document.getElementById("button1Output");
        button1Output.innerText =
        mouseEvent.type
        + ": (" + mouseEvent.clientX + "," + mouseEvent.clientY + ")";

    }

    app.start();
})();

如果您是在標記中而不是程式碼中設定事件處理常式,則前述範例中的按鈕看起來會像這樣:

<!-- Incorrect code. Do not use this in your solution. -->
<button id="button1" onclick="button1Click(event)">An HTML button</button>

當您執行應用程式且按一下按鈕時,不會執行任何動作。這是因為 button1Click 函式包裝在匿名函式中,所以您的標記無法直接存取該函式。 為了讓程式碼運作,您需要將 button1Click 移到匿名函式外。

(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    app.start();
})();

function button1Click(mouseEvent) {
    var button1Output = document.getElementById("button1Output");
    button1Output.innerText =
    mouseEvent.type
    + ": (" + mouseEvent.clientX + "," + mouseEvent.clientY + ")";

}

不過,現在 button1Click 為全域,這也不是我們想要的情況。較好的方法是將 button1Click 定義移回匿名函式中,然後使用 WinJS.Namespace.define 讓它變成可公開存取 (如需這項操作的範例,請參閱 如何以宣告方式設定事件處理常式)。

備註

請勿使用 JavaScript URI

不要在事件處理常式中使用 JavaScript URI,因為應用程式不會執行 URI。例如,如果您嘗試這麼做,按一下按鈕時不會執行任何動作:

<!-- Incorrect code. Do not use this in your solution. -->
<button id="button1" onclick="javascript: 2 + 2;">An HTML Button</button>

這項限制會套用到應用程式本機內容中的程式碼 (應用程式套件中包含的程式碼),但是不會套用到您的應用程式存取的外部網頁上的程式碼。

使用表單

在傳統 HTML 網站中,控制項和其他輸入元素通常包含在 form 元素中。form 元素用來將資料傳遞至伺服器。由於大部分傳統應用程式的程式設計是以用戶端為主,因此通常不需要使用 form 元素。

使用透明圖層

常見的做法是使用全螢幕透明圖層 (例如空的 div 元素) 來偵測特定使用者互動或顯示動畫。不過,以透明圖層涵蓋 HTML 控制項,可能會使它在回應使用者互動時較為遲緩。若要維持 HTML 控制項的回應性,請不要以透明圖層加以覆蓋。

摘要與後續步驟

您已學會如何建立 HTML 控制項以及如何附加事件處理常式。

接下來,請閱讀 快速入門:新增 WinJS 控制項與樣式,了解如何使用新的 WinJS 控制項 (針對使用 JavaScript 的 Windows 執行階段應用程式所提供)。

若要深入了解特定的控制項,請參閱 控制項清單

範例

相關主題

撰寫基本應用程式的程式碼
快速入門:新增 WinJS 控制項與樣式
控制項清單

 

 

Microsoft 正展開一份線上問卷調查,了解您對於網站的看法。如果您選擇參加,您離開網站時即會顯示線上問卷調查。

您是否想要參加?