774 Stimmen

Wie setzt man den Fokus auf ein Eingabefeld?

Was ist der 'Angular Way', um den Fokus auf ein Eingabefeld in AngularJS zu setzen?

Weitere spezifische Anforderungen:

  1. Wenn ein Modal geöffnet wird, den Fokus auf ein vordefiniertes innerhalb dieses Modals setzen.
  2. Jedes Mal, wenn ein sichtbar wird (z. B. durch Klicken auf eine Schaltfläche), den Fokus darauf setzen.

Ich habe versucht, die erste Anforderung zu erreichen mit autofocus, aber das funktioniert nur, wenn das Modal zum ersten Mal geöffnet wird, und nur in bestimmten Browsern (z. B. in Firefox funktioniert es nicht).

4voto

Shawn Dotey Punkte 616

Ein einfaches, das gut mit Modals funktioniert:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {

            $timeout(function ()
            {
                element[0].focus();
            });

        }
    };
}])

Beispiel

3voto

Tsuneo Yoshioka Punkte 6784

Wahrscheinlich die einfachste Lösung im ES6-Zeitalter.

Das Hinzufügen der folgenden einzeiligen Direktive macht das HTML 'autofocus'-Attribut in Angular.js wirksam.

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

Jetzt können Sie einfach die HTML5-Autofokus-Syntax verwenden:

3voto

Ludovic Guillaume Punkte 3197

Dies ist auch möglich, ngModelController zu verwenden. Funktioniert mit 1.6+ (weiß nicht mit älteren Versionen).

HTML

JS

$scope.myForm.myText.$$element.focus();

--

N.B.: Je nach Kontext müssen Sie möglicherweise eine Timeout-Funktion verwenden.

N.B.²: Bei Verwendung von controllerAs ist dies fast dasselbe. Ersetzen Sie nur name="myForm" durch name="vm.myForm" und in JS, vm.myForm.myText.$$element.focus();.

3voto

joshperry Punkte 39356

Mark und Blesh haben großartige Antworten; jedoch hat Marks Antwort einen Fehler, den Blesh (abgesehen davon, dass sie komplex zu implementieren ist) aufzeigt, und ich finde, dass Blesh's Antwort einen semantischen Fehler enthält, wenn es darum geht, einen Service zu erstellen, der sich speziell darauf konzentriert, Fokus-Anfragen an das Frontend zu senden, wenn er eigentlich nur einen Weg brauchte, um das Ereignis zu verzögern, bis alle Direktiven zuhören.

Also hier ist, was ich letztendlich gemacht habe, das sich stark von Blesh's Antwort inspirieren lässt, aber die Semantik des Controller-Ereignisses und des "nach Laden"-Services separat hält.

Dies ermöglicht es, das Controller-Ereignis leicht für andere Dinge als nur das Fokussieren eines bestimmten Elements anzuschließen, und erlaubt auch, den Overhead der "nach Laden"-Funktionalität nur zu verursachen, wenn es benötigt wird, was in vielen Fällen nicht der Fall sein muss.

Verwendung

app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

Quelltext

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});

3voto

ibaixas Punkte 131

Sie könnten einfach eine Direktive erstellen, die den Fokus auf das dekorierte Element setzt postLinking:

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

Dann in Ihrem html:

Dies würde für Modale und ng-if toggled Elemente funktionieren, nicht für ng-show, da postLinking nur beim HTML-Verarbeitung passiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X