quitar foco evento ejemplo detectar javascript jquery angularjs

foco - onblur javascript ejemplo



Fácil manipulación dom en AngularJS-haga clic en un botón, luego configure el foco en un elemento de entrada (7)

La manipulación del DOM debe estar en una directiva en lugar del controlador. focusInput una directiva focusInput y la usaría en el botón:

<div class="button" focus-input>{{element.name}}</div>

Directiva:

app.directive(''focusInput'', function($timeout) { return { link: function(scope, element, attrs) { element.bind(''click'', function() { $timeout(function() { element.parent().parent().find(''input'')[0].focus(); }); }); } }; });

Plunker

Como jqLite es bastante limitado en cuanto a los métodos de cruce DOM, tuve que usar parent().parent() . Es posible que desee utilizar jQuery o algunos métodos de JavaScript.

Como ya descubrió, se necesita $timeout para que se llame al método focus() después de que el navegador renderice (es decir, termine de manejar el evento click).

find(''input'')[0] nos da acceso al elemento DOM, lo que nos permite utilizar el método JavaScript focus() (en lugar de find(''input'').focus() que requeriría jQuery).

Tengo este código angular:

<div class="element-wrapper" ng-repeat="element in elements"> <div class="first-wrapper"> <div class="button" ng-click="doSomething(element,$event)">{{element.name}}</div> </div> <div class="second-wrapper"> <input type="text" value="{{element.value}}"> </div> </div>

Lo que quiero que suceda: cuando el usuario hace clic en el botón, el elemento de entrada se enfocará.

¿Cómo encuentro el elemento de entrada después de hacer clic en el elemento del botón y enfocarlo?

Puedo hacer una función que se ve así:

function doSomething(element,$event) { //option A - start manipulating in the dark: $event.srcElement.parentNode.childNodes[1] //option B - wrapping it with jQuery: $($event.srcElement).closest(''.element-wrapper'').find(''input'').focus(); }

Ninguno de los dos trabaja - ¿Hay una forma angular mejor para hacerlo? ¿Utiliza funciones como .closest() y .find() como en jQuery?

Actualizar:

Encontré este truco para estar trabajando (pero todavía no parece ser la solución correcta) :

function doSomething(element,$event) { setTimeout(function(){ $($event.srcElement).closest(''.element-wrapper'').find(''input'').focus(); },0) }

Lo estoy envolviendo con setTimeout así que después de que Angular termine todas sus manipulaciones se enfoca en el elemento de entrada.


Hace poco estuve mirando AngularJS y encontré una situación similar.

Estaba trabajando para actualizar la aplicación de ejemplo Todo desde la página angular principal para agregar un modo "editar" cuando haces doble clic en un elemento pendiente.

Pude resolver mi problema usando un enfoque basado en el modelo / estado. Si su aplicación funciona de manera similar (desea establecer el foco en un campo cuando alguna condición en el modelo es verdadera), entonces esto podría funcionar para usted también.

Mi enfoque es establecer la propiedad model.editing en true cuando el usuario hace doble clic en la etiqueta de model.editing pendientes, esto muestra la entrada editable y oculta la etiqueta regular no editable y la casilla de verificación. También tenemos una directiva personalizada llamada focusInput que tiene un reloj en la misma propiedad model.editing y establecerá el foco en el campo de texto cuando el valor cambie:

<li ng-repeat="todo in todos"> <div> <!-- Regular display view. --> <div ng-show="todo.editing == false"> <label class="done-{{todo.done}}" ng-dblclick="model.editing = true"> <input type="checkbox" ng-model="todo.done"/>{{todo.text}} </label> </div> <!-- Editable view. --> <div ng-show="todo.editing == true"> <!-- - Add the `focus-input` directive with the statement "todo.editing == true". This is the element that will receive focus when the statement evaluates to true. - We also add the `todoBlur` directive so we can cancel editing when the text field loses focus. --> <input type="text" ng-model="todo.text" focus-input="todo.editing == true" todo-blur="todo.editing = false"/> </div> </div> </li>

Aquí está la directiva focusInput que establecerá el foco en el elemento actual cuando alguna condición se evalúa como true :

angular.module(''TodoModule'', []) // Define a new directive called `focusInput`. .directive(''focusInput'', function($timeout){ return function(scope, element, attr){ // Add a watch on the `focus-input` attribute. // Whenever the `focus-input` statement changes this callback function will be executed. scope.$watch(attr.focusInput, function(value){ // If the `focus-input` statement evaluates to `true` // then use jQuery to set focus on the element. if (value){ $timeout(function(){ element.select(); }); } }); }; }) // Here is the directive to raise the ''blur'' event. .directive(''todoBlur'', [ ''$parse'', function($parse){ return function(scope, element, attr){ var fn = $parse(attr[''todoBlur'']); return element.on(''blur'', function(event){ return scope.$apply(function(){ return fn(scope, { $event: event }); }); }); }; } ]);


Tuve que crear una cuenta solo para proporcionar la respuesta fácil.

//Add a bool to your controller''s scope that indicates if your element is focused ... //ellipsis used so I don''t write the part you should know $scope.userInputActivate = false; ... //Add a new directive to your app stack ... .directive(''focusBool'', function() { return function(scope, element, attrs) { scope.$watch(attrs.focusBool, function(value) { if (value) $timeout(function() {element.focus();}); }); } }) ... <!--Now that our code is watching for a scope boolean variable, stick that variable on your input element using your new directive, and manipulate that variable as desired.--> ... <div class="button" ng-click="userInputActivate=true">...</div> ... <input type="text" focus-Bool="userInputActivate"> ...

Asegúrese de restablecer esta variable cuando no esté utilizando la entrada. Puede agregar una directiva ng-blur lo suficientemente fácil como para volver a cambiarla u otro evento ng-click que lo restablezca a falso. Establecerlo en falso simplemente lo prepara para la próxima vez. Aquí hay un ejemplo de directiva ng-blur que encontré en caso de que tenga problemas para encontrar uno.

.directive(''ngBlur'', [''$parse'', function($parse) { return function(scope, element, attr) { var fn = $parse(attr[''ngBlur'']); element.bind(''blur'', function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); } }]);


Esto es lo que se me ocurrió. Comencé con la solución anterior de Mark Rajcok y luego lo moví para que sea fácil de reutilizar. Es configurable y no requiere ningún código en su controlador. El enfoque es puro aspecto de presentación y no debería requerir código de controlador

html:

<div id="focusGroup"> <div> <input type="button" value="submit" pass-focus-to="focusGrabber" focus-parent="focusGroup"> </div> <div> <input type="text" id="focusGrabber"> </div> </div>

directiva:

chariotApp.directive(''passFocusTo'', function ($timeout) { return { link: function (scope, element, attrs) { element.bind(''click'', function () { $timeout(function () { var elem = element.parent(); while(elem[0].id != attrs.focusParent) { elem = elem.parent(); } elem.find("#"+attrs.passFocusTo)[0].focus(); }); }); } }; });

suposición:

  • Tu dador y tomador están cerca.
  • cuando se usa esto varias veces en una página, los id utilizados son únicos o los que dan y reciben están en una rama aislada del DOM.

Aquí hay una directiva que desencadena un evento de enfoque en un elemento dom de destino:

Directiva AngularJs:

app.directive(''triggerFocusOn'', function($timeout) { return { link: function(scope, element, attrs) { element.bind(''click'', function() { $timeout(function() { var otherElement = document.querySelector(''#'' + attrs.triggerFocusOn); if (otherElement) { otherElement.focus(); } else { console.log("Can''t find element: " + attrs.triggerFocusOn); } }); }); } }; });

El html:

<button trigger-focus-on="targetInput">Click here to focus on the other element</button> <input type="text" id="targetInput">

Un ejemplo en vivo en Plunker


Para usar el método .closest () sugiero que apliques un prototipo de mecanismo de herencia fox para expandir las oportunidades angulares. Solo así:

angular.element.prototype.closest = (parentClass)-> $this = this closestElement = undefined while $this.parent() if $this.parent().hasClass parentClass closestElement = $this.parent() break $this = $this.parent() closestElement

Margen:

<span ng-click="removeNote($event)" class="remove-note"></span>

Uso:

$scope.removeNote = ($event)-> currentNote = angular.element($event.currentTarget).closest("content-list_item") currentNote.remove()


Para encontrar la entrada, agregue Id <input id="input{{$index}}" .. /> y pase ngRepeat index como parámetro para la función ng-click="doSomething(element,$event, $index)"

<div class="element-wrapper" ng-repeat="element in elements"> <div class="first-wrapper"> <div class="button" ng-click="doSomething(element,$event, $index)">{{element.name}}</div> </div> <div class="second-wrapper"> <input id="input{{$index}}" type="text" value="{{element.value}}"> </div> </div>

En la función use $timeout con cero demora para esperar hasta el final de la renderización de DOM. Entonces la entrada puede ser encontrada por getElementById en $timeout function. No olvides agregar $timeout al controlador.

.controller("MyController", function ($scope, $timeout) { $scope.doSomething = function(element,$event, index) { //option A - start manipulating in the dark: $event.srcElement.parentNode.childNodes[1] $timeout(function () { document.getElementById("input" + index).focus(); }); } });