入力フィールドにフォーカスを設定するにはどうすればいいですか? 質問する

入力フィールドにフォーカスを設定するにはどうすればいいですか? 質問する

AngularJS の入力フィールドにフォーカスを設定するための「Angular の方法」とは何ですか?

より具体的な要件:

  1. ときモーダルモーダルが開かれたら、<input>このモーダル内の定義済み項目にフォーカスを設定します。
  2. 表示されるたびに<input>(たとえば、何らかのボタンをクリックするなど)、それにフォーカスを設定します。

私は最初の要件を達成しようとしましたを使用しますautofocusが、これはモーダルが初めて開かれたときのみ、特定のブラウザでのみ機能します (たとえば、Firefox では機能しません)。

ベストアンサー1

  1. モーダルが開かれると、このモーダル内の定義済み <input> にフォーカスが設定されます。

ディレクティブを定義し、プロパティ/トリガーを $watch して、要素にフォーカスするタイミングを認識できるようにします。

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

プランカー

モーダルをレンダリングする時間を与えるために $timeout が必要なようです。

'2.' <input> が表示されるたびに (たとえば、ボタンをクリックするなど)、それにフォーカスを設定します。

基本的に上記のようなディレクティブを作成します。スコープ プロパティを監視し、それが true になったら (ng-click ハンドラーで設定) を実行しますelement[0].focus()。ユース ケースによっては、これに $timeout が必要な場合と、そうでない場合があります。

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

プランカー


2013 年 7 月更新: オリジナルの isolate スコープ ディレクティブを使用した人が、埋め込み入力フィールド (つまり、モーダル内の入力フィールド) で問題を抱えているのを何人か見てきました。新しいスコープのないディレクティブ (または新しい子スコープ) を使用すると、問題がいくらか軽減されるはずです。そのため、上記の回答を更新して、isolate スコープを使用しないようにしました。以下は、元の回答です。

分離スコープを使用した 1. の元の回答:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

プランカー

分離スコープを使用した 2. の元の回答:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

プランカー

ディレクティブ内のトリガー/focusInput プロパティをリセットする必要があるため、双方向データバインディングには '=' が使用されます。最初のディレクティブでは、'@' で十分でした。また、'@' を使用する場合、@ は常に文字列になるため、トリガー値を "true" と比較することに注意してください。

おすすめ記事