См. РЕДАКТИРОВАНИЕ ниже для получения наиболее актуальной новой информации.

В директиве angular у меня есть элемент div. Я ищу потомков, которые являются входами, и хватаю первого из них, к которому нужно применить фокус.

var nodes = element[0].querySelectorAll('input, button');

Я могу получить доступ к нужному входу с помощью nodes [0], но я не могу понять, как выполнить для него вызов focus ().

nodes[0].focus() does not work
$(nodes[0]).focus() does not work
angular.element(nodes[0]) does not work

Когда я печатаю список узлов на консоли:

NodeList [ <button.yes.btn.btn-default>, <button.no.btn.btn-default> ]

Когда я выбираю узлы [0] и печатаю на консоли:

<button data-ng-click="showMismatchWarning = false; verifyRentalItemsMatch()" class="yes btn btn-default" type="button" answer="">

Например, это кнопка, к которой я хотел бы применить focus (). Я просто не могу понять, как перейти от результата queryselector к выполнению собственного html focus ()


ИЗМЕНИТЬ (НАИБОЛЕЕ ВАЖНАЯ ИНФОРМАЦИЯ):

Дальнейшая информация. У меня разные вкладки, поэтому они скрыты. Но директива применяется к тому же логическому выражению isPage (x), поэтому элементы DOM должны быть видны к этому моменту времени.

<div ng-show="isPage(1)" myFocus="isPage(1)">
  <input> <--- this very first one focus() seems to work
</div>

<div ng-show=isPage(2)" myFocus="isPage(2)">
  <input> <--- this one the focus() never works
</div>

Если подумать об этом больше, должно быть, что focus () выполняется до того, как элемент DOM станет полностью видимым, поэтому focus () не работает. Но директива $ наблюдает за атрибутами и следит за тем, чтобы это же выражение стало истинным, почему оно должно выполняться до ng-show?

Вот моя директива для справки.

"use strict";
angular.module('something').directive("myfocus", function() {
    return {
        link: function(scope, element, attributes) {
            scope.$watch(attributes.focuson, function(newValue) {
                if(newValue) {
                    highlightAndFocus(element[0]);
                }
            },true);

            function highlightAndFocus(node) {
                var task = $(node);
                task.focus();
                task.addClass('highlight');

                var nextInput = node.querySelector('input, button:not(#cancel)');
                nextInput.focus();
                console.log(nextInput);

            }
        }
    };
});
3
Milan Novaković 24 Дек 2016 в 02:16
2
Что здесь element? Можете ли вы опубликовать, как выглядит ваш nodeList?
 – 
jmargolisvt
24 Дек 2016 в 02:24
Обновлено, чтобы включить дополнительную информацию. Элемент - это div, содержащий входные данные.
 – 
Milan Novaković
24 Дек 2016 в 02:30
Первый, nodes[0].focus(), должен работать. Что происходит, когда он терпит неудачу? Что заканчивается фокусом сразу после того, как вы пытаетесь сфокусировать элемент?
 – 
Douglas
24 Дек 2016 в 02:36
Видны ли элементы, на которые нужно сфокусироваться? Fwiw, в отличие от jQuery, в стандартном DOM вам не нужно выбирать все элементы, если вам нужен только первый один : используйте querySelector() (не …All()) - возвращает сам элемент или null, если элемент не найден.
 – 
Marat Tanalin
24 Дек 2016 в 02:38
Ничто не попадает в фокус. Это просто не работает. Так что на самом деле я фокусируюсь на div, затем применяю к нему класс, затем ищу входные данные, а затем пытаюсь сосредоточиться на первом входе. Класс применен, но фокусы, похоже, не работают, кроме самого первого.
 – 
Milan Novaković
24 Дек 2016 в 02:48

1 ответ

Лучший ответ

Элемент, на который нужно сфокусироваться, очевидно, не виден в момент вызова focus(). Используйте ненулевой тайм-аут, чтобы отложить фокусировку, или встроенную функцию (если она существует) платформы для определения момента, когда элемент становится видимым.

В качестве альтернативы попробуйте прочитать свойство offsetWidth (или offsetHeight) элемента, на который нужно сфокусироваться, чтобы принудительно переформатировать / перерисовать страницу перед установкой фокуса.

1
Marat Tanalin 24 Дек 2016 в 04:00
Как мы уже обсуждали, это не идеально, но похоже, что единственный способ заставить его работать - это установить некоторый период таймера. 10 мс вроде всегда работают. Более низкое значение ненадежно.
 – 
Milan Novaković
24 Дек 2016 в 03:40
Вы даже можете рассмотреть возможность установки нового таймера, когда setfocus не удается. Конечно, повторите ограниченное количество раз ...
 – 
GolezTrol
24 Дек 2016 в 03:45
Как добавлено, я понизил уровень приоритета моей директивы до -1, потому что ng-show равен 0. Это, похоже, имело некоторый эффект, потому что теперь с указанным таймаутом 0 мс он будет иногда устанавливать фокус. К сожалению, все еще кажется, что нужно указать какой-то тайм-аут ...
 – 
Milan Novaković
24 Дек 2016 в 03:56