HOWTO · Angular

在 Angular 中的輸入欄位上設定焦點

本教程通過示例演示如何在 Angular 中的輸入欄位上設定焦點。

本頁內容

表單顯示後,使用會呼叫 DOM 元素 focus() 方法的自訂指令,即可在輸入欄位出現時將焦點移至該欄位。以下範例使用的是舊版框架 AngularJS 1.x,並非現代 Angular 的範例。ng-model 會將輸入欄位的值繫結至模型屬性,但不會設定欄位焦點,也不會驗證欄位內容。

在 Angular 中設定輸入欄位焦點的步驟

先用一個簡化的替代物,單獨示範 focus() 呼叫的效果。這段 JavaScript 範例不會執行 AngularJS 或瀏覽器;完整的瀏覽器端設定如下。

執行以下範例:

const input = {
  focused: false,
  focus() {
    this.focused = true;
  }
};

input.focus();
console.log(`Focused: ${input.focused}`);

輸出會顯示 Focused: true,表示這個簡化範例中的輸入欄位已取得焦點。標籤 Focused: 保持英文,未予翻譯。

Focused: true

在 AngularJS 中,請將指令註冊到與控制器相同的模組,再把 focus-me 屬性加到輸入欄位上。按鈕的點擊處理程式會顯示表單並設定焦點觸發值。短暫的 $timeout 可讓 AngularJS 先完成檢視更新,再由指令將焦點移至已顯示的元素。

以下獨立的瀏覽器頁面包含模組、控制器、指令和標記。如果應用程式不使用 CDN,請將 AngularJS 指令碼網址換成由本機託管的副本。此頁面使用 AngularJS 1.0.4,以符合原始範例所示的版本;這裡展示此舊版僅供參考,不建議用於新應用程式。

<!doctype html>
<html ng-app="focusDemo">
<head>
  <meta charset="utf-8">
  <title>AngularJS input focus</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
  <script>
    var app = angular.module('focusDemo', []);

    app.controller('DemoController', ['$scope', function($scope) {
      $scope.showForm = false;
      $scope.focusInput = false;
    }]);

    app.directive('focusMe', ['$timeout', function($timeout) {
      return {
        scope: { focusMe: '=' },
        link: function(scope, element) {
          scope.$watch('focusMe', function(value) {
            if (value) {
              $timeout(function() {
                element[0].focus();
                scope.focusMe = false;
              });
            }
          });
        }
      };
    }]);
  </script>
</head>
<body ng-controller="DemoController">
  <button type="button" ng-click="showForm = true; focusInput = true">
    Show the form
  </button>

  <div ng-show="showForm">
    <label for="name">Name</label>
    <input id="name" type="text" ng-model="name" focus-me="focusInput">
    <button type="button" ng-click="showForm = false">Done</button>
    <p>The browser's focus indicator marks the active input.</p>
  </div>
</body>
</html>

AngularJS 會將 focus-me 屬性正規化為指令名稱 focusMe。指令的隔離作用域屬性使用與該屬性相同的名稱,而 = 繫結會將它連接到控制器上的 focusInput。按鈕將該值設為 true 時,監看器會在檢視更新後排定焦點設定;接著它會重設該值,讓這個動作可以再次觸發。輸入欄位必須可見且已啟用,瀏覽器才能將焦點移至該欄位。瀏覽器會依照自身樣式繪製焦點指示,因此其外觀可能因瀏覽器和佈景主題而異。

焦點會將鍵盤游標移至欄位,但不會確認欄位值是否有效,也無法防止輸入錯誤。若需要輸入規則,請另外加入 AngularJS 表單驗證。ngBlur 會在元素失去焦點時觸發,例如使用者按 Tab 鍵移開欄位時;設定欄位焦點或讓焦點離開欄位都不需要用到它。此瀏覽器範例未經執行驗證。

表單出現時,這種做法可以省去一次點擊,並清楚指出接下來可輸入文字的位置。請謹慎使用自動設定焦點:若焦點移動出乎使用者預期,可能會讓鍵盤或螢幕閱讀器使用者感到困惑,尤其是在較長的操作流程中。請保留清楚可見的標籤和明確的 Tab 鍵順序,並讓使用者在欄位取得焦點後仍能照常移動焦點。