¿Cómo establecer el foco en el campo de entrada?

Este artículo fue traducido de: ¿Cómo establecer el foco en el campo de entrada?

¿Cuál es la "forma angular" para establecer el foco en el campo de entrada en AngularJS? ¿Cuál es la "forma angular" para establecer el foco en el campo de entrada en AngularJS ?

Requisitos más específicos: Requisitos más específicos:

  1. Cuando se abre un Modal , enfóquese en un predefinido <input>dentro de este Modal. Después de abrir una modalidad , concéntrese en el predefinido dentro de esta modalidad <input>.
  2. Cada <input> vez que sea ​​visible (por ejemplo, haciendo clic en un botón), establezca el foco en él. Siempre que sea ​​visible (por ejemplo, haciendo clic en algunos botones), establezca el foco en él .<input>

Traté de cumplir el primer requisito con autofocus, pero esto funciona solo cuando el Modal se abre por primera vez, y solo en ciertos navegadores (por ejemplo, en Firefox no funciona). Traté de autofocus cumplir el primer requisito , pero esto Solo funciona cuando se abre Modal por primera vez, y solo funciona en algunos navegadores (por ejemplo, no funciona en Firefox).

Cualquier ayuda será apreciada, cualquier ayuda será apreciada .


Piso # 1

Referencia: https://stackoom.com/question/10EpC/ Cómo establecer el foco en los campos de entrada


# 2F

  1. Cuando se abre un Modal, establezca el foco en un <input> predefinido dentro de este Modal. Después de abrir una modalidad, concéntrese en el <input> predefinido dentro de esta modalidad.

Defina una directiva y haga que $ mire una propiedad / disparador para que sepa cuándo enfocar el elemento: defina una directiva y haga que $ mire una propiedad / disparador para que sepa cuándo enfocar el elemento :

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));
            });
        }
    };
}]);

Émbolo émbolo

$ Timeout parece ser necesario para dar tiempo modal para renderizar. $ Timeout parece requerir el tiempo modal dado para renderizar.

'2.' '2. Cada vez que <input> sea visible (por ejemplo, haciendo clic en algún botón), establezca el foco en él. Siempre que <input> se vuelva visible (por ejemplo, haciendo clic en algún botón), establezca el foco en él .

Crea una directiva esencialmente como la de arriba Crea una directiva que sea básicamente similar a la de arriba . Algunos alcance Property Watch, y se convierte en Cuando verdadero (que se había marcado en su ng clic Handler), Ejecutar element[0].focus(). Observar algún atributo alcance, cuando se convierte en verdadera (en el manipulador ng clic) se ejecuta element[0].focus(). Dependiendo de su caso de uso, es posible que necesite o no un tiempo de espera de $ para este: Dependiendo de su caso de uso, puede o no necesitar un tiempo de espera de $:

<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;
          //});
        }
      });
    }
  };
});

Émbolo émbolo


Actualización 7/2013 : He visto a algunas personas usar mis directivas de alcance de aislamiento original y luego tienen problemas con los campos de entrada incrustados (es decir, un campo de entrada en el modal) Actualización 7/2013 : He visto a algunas personas usarme La instrucción de rango de aislamiento original encontró problemas con el campo de entrada incrustado (es decir, el campo de entrada en el modal). Una directiva sin un nuevo alcance (o posiblemente un nuevo alcance infantil) debería aliviar algo del dolor. Una instrucción sin un nuevo alcance (o posiblemente un nuevo alcance infantil) debería aliviar algo del dolor. Así que arriba actualicé la respuesta para no usar ámbitos aislados. Así que arriba, actualicé la respuesta para no usar ámbitos aislados . A continuación se muestra la respuesta original: La siguiente es la respuesta original:

Respuesta original para 1., usando un alcance aislado: 1. Respuesta original para usar un alcance aislado :

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(); 
          });
        }
      });
    }
  };
});

Plunker . Émbolo .

Respuesta original para 2., usando un alcance aislado: 2. Respuesta original para usar un alcance aislado :

<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;
          //});
        }
      });
    }
  };
});

Plunker . Émbolo .

Dado que necesitamos restablecer la propiedad trigger / focusInput en la directiva, '=' se usa para el enlace de datos bidireccional. Dado que necesitamos restablecer la propiedad trigger / focusInput en la directiva, "=" se usa para el enlace de datos bidireccional . En la primera directiva, '@' era suficiente, en la primera directiva, "@" es suficiente. También tenga en cuenta que cuando use '@', comparemos el valor de disparo con "verdadero" ya que @ siempre da como resultado una cadena. También tenga en cuenta que cuando use "@", comparemos el valor de disparo con "verdadero" porque @ siempre Producirá una cuerda.


Piso # 3

En primer lugar, de manera oficial que hacer es en el enfoque en el Plan de trabajo para 1.1 . En primer lugar, el método oficial enfoque es 1.1 de la hoja de ruta . Mientras tanto, puede escribir una directiva para implementar el enfoque de configuración. Al mismo tiempo, puede escribir una directiva para lograr el enfoque de configuración.

En segundo lugar, establecer el foco en un elemento después de que se haya vuelto visible actualmente requiere una solución alternativa. Segundo, para establecer el foco en el elemento actualmente visible, se necesita una solución. Simplemente retrase su llamada al elemento focus () con a $timeout. Solo use $timeoutdelay para llamar al elemento focus ()

Debido a que existe el mismo problema de controlador-modifica-DOM para el enfoque, desenfoque y selección, propongo tener una ng-targetdirectiva: dado que existe el mismo problema de controlador-modificado-DOM en foco, desenfoque y selección, sugiero usar la ng-targetdirectiva:

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

El hilo aquí Papel pintado Angular: http://goo.gl/ipsx4 , la escribió en su blog detalles aquí salvapantallas y mucho más: http://goo.gl/4rdZa aquí rosca de ángulo: HTTP : //goo.gl/ipsx4 , más detalles en Publicado aquí : http://goo.gl/4rdZa

Creará un acuerdo con la Directiva de la .focus()función como responsable del tratamiento Dentro de su especificada por el ng-targetatributo. Las siguientes instrucciones ng-targetde crear un controlador interno propiedades especificadas .focus()funciones. (Se crea una .blur()y A .select()DEMASIADO.) Demostración: http://jsfiddle.net/bseib/WUcQX/ (que .blur()crea una .blur()y una .select().) Demostración: HTTP : //jsfiddle.net/bseib/WUcQX/


# 4F

He escrito una directiva de enfoque vinculante bidireccional, al igual que el modelo recientemente. Escribí una directiva de enfoque vinculante bidireccional, como el modelo más reciente.

Puede usar la directiva de enfoque de esta manera: Puede usar la directiva de enfoque de esta manera :

<input focus="someFocusVariable">

Si realiza alguna variable de alcance de FocusVariable trueen cualquier parte de su controlador, la entrada se enfocará. Si realiza alguna variable de alcance de FocusFariable en cualquier posición del controlador true, la entrada se convertirá en el foco. Y si desea "desenfocar" su entrada, someFocusVariable se puede establecer en falso. Y, si desea "desenfocar" la entrada, puede establecer someFocusVariable en falso. Es como la primera respuesta de Mark Rajcok pero con enlace bidireccional, como la primera respuesta de Mark Rajcok, pero con enlace bidireccional .

Aquí está la directiva: Esta es la directiva:

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

Uso: Uso:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

Aquí está el violín: Este es el violín:

http://fiddle.jshell.net/ubenzer/9FSL4/8/ http://fiddle.jshell.net/ubenzer/9FSL4/8/


# 5F

(EDITAR: he agregado una solución actualizada debajo de esta explicación) (EDITAR: agregué una solución actualizada debajo de esta explicación )

Mark Rajcok es el hombre ... y su respuesta es una respuesta válida, pero ha tenido un defecto (lo siento Mark) ... Mark Rajcok es esta persona ... su respuesta es válida la respuesta, pero hay defectos (Marcar lo siento) ...

... Intente usar el booleano para enfocar la entrada, luego desenfoque la entrada, luego intente usarla para enfocar la entrada nuevamente ... Intente usar el booleano para enfocar la entrada, luego desenfoque la entrada, luego intente usarla Enfoca la entrada de nuevo. No funcionará a menos que restablezca el valor booleano a falso, luego $ digest, luego lo restablezca a verdadero. No funcionará a menos que restablezca el valor booleano a falso y luego restablezca $ digest a verdadero. Incluso si usa una comparación de cadenas en su expresión, se verá obligado a cambiar la cadena a otra cosa, $ digest, luego volver a cambiarla. Incluso si usa la comparación de cadenas en la expresión, tendrá que cambiar la cadena A $ digest, y luego cámbielo. (Esto se ha abordado con el controlador de eventos de desenfoque). (Esto se ha abordado con el controlador de eventos de desenfoque ).

Por lo tanto, propongo esta solución alternativa: por lo tanto, propongo esta solución alternativa :

Use un evento, la característica olvidada de Angular Use un evento, la característica olvidada de Angular .

JavaScript ama los eventos después de todo. JavaScript ama los eventos después de todo . Los eventos están inherentemente acoplados de manera flexible, y aún mejor, evitas agregar otro $ watch a tu $ digest. Los eventos están inherentemente sueltos de acoplamiento, y aún mejor, evitas agregar otro $ watch en $ digest.

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

Entonces ahora puedes usarlo así: Ahora puedes usarlo así :

<input type="text" focus-on="newItemAdded" />

y luego en cualquier lugar de tu aplicación ... y luego en cualquier lugar de tu aplicación ...

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

Esto es increíble porque puedes hacer todo tipo de cosas con algo como esto. Esto es genial porque puedes hacer todo tipo de cosas con tales cosas. Por un lado, puede vincular los eventos que ya existen. Primero, puede vincular los eventos que ya existen . Por otra parte, comienzas a hacer algo inteligente al hacer que diferentes partes de tu aplicación publiquen eventos a los que otras partes de tu aplicación pueden suscribirse. Por otro lado, puedes permitir que otras partes de la aplicación publiquen eventos permitiendo diferentes partes de la aplicación Suscríbase para comenzar a hacer cosas inteligentes.

De todos modos, este tipo de cosas me grita "impulsado por un evento. De todos modos, este tipo de cosas es un grito" impulsado por un evento "para mí. Creo que, como desarrolladores de Angular, nos esforzamos mucho para clavar clavijas con forma de telescopio en agujeros con forma de evento. Creo que, como desarrolladores de Angular, trabajamos muy duro para martillar clavos con forma de telescopio en agujeros con forma de evento.

¿Es la mejor solución? ¿Es la mejor solución ? No lo sé , no lo sé. Es una solución, es una solución.


Solución actualizado solución de actualización

Después del comentario de @ ShimonRachlenko a continuación, he cambiado ligeramente mi método de hacer esto. Después de que @ShimonRachlenko comentó a continuación, he cambiado ligeramente el método de hacer esto . Ahora uso una combinación de un servicio y una directiva que maneja un evento "detrás de escena": Ahora, uso una combinación de un servicio y una directiva para manejar "detrás de escena":

Aparte de eso, es el mismo director descrito anteriormente, además de eso, es el mismo director descrito anteriormente .

Aquí hay una demostración rápida Plunk

uso uso

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

Recursos fuente

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

app.factory('focus', function ($rootScope, $timeout) {
  return function(name) {
    $timeout(function (){
      $rootScope.$broadcast('focusOn', name);
    });
  }
});

Piso # 6

También puede usar la función jqlite incorporada de angular.

angular.element('.selector').trigger('focus');

Publicado 0 artículos originales · elogiado 75 · 560,000 vistas +

Supongo que te gusta

Origin blog.csdn.net/w36680130/article/details/105447386
Recomendado
Clasificación