$ .focus () не работает

155

Последний пример JQuery в focus()документации состояний

$('#id').focus()

должен сделать ввод сфокусированным (активным). Я не могу заставить это работать.

Даже в консоли на этом сайте, я пытаюсь это для окна поиска

$('input[name="q"]').focus()

и я ничего не получаю. Любые идеи?

Сэм Селикофф
источник
2
Можете ли вы показать нам свой код?
Адил
Нам нужно знать больше, потому что это хорошо работает для меня: jsfiddle.net/G7hwR/1 просто нажмите в любом месте на правой панели, и это фокусируется ...
Роб Г
Не должен ли акцент на этой странице работать, хотя? Фрагмент, который я предоставил?
Сэм Селикофф
Это зависит от того, в чем оно содержится; если он не находится внутри чего-либо, скорее всего, он запускается еще до того, как страница рендерится ...
Rob G
Для тех, кто приходит сюда из поиска: встроенные в браузер инструменты разработчика могут помешать функционалу focus(). Больше информации
17

Ответы:

392

На самом деле пример, который вы привели для фокусировки на этом сайте, работает отлично, если вы не сфокусированы на консоли. Причина, по которой это не работает, заключается просто в том, что он не крадет фокус с консоли разработчика. Если вы запустите следующий код в своей консоли, а затем быстро щелкнете в окне браузера после этого, вы увидите, что он сфокусируется на окне поиска:

setTimeout(function() { $('input[name="q"]').focus() }, 3000);

Что касается вашего другого, единственное, что доставляло мне неприятности в прошлом, это порядок событий. Вы не можете вызвать focus () для элемента, который не был присоединен к DOM. Элемент, который вы пытаетесь сфокусировать, уже подключен к DOM?

Джастин Варкентин
источник
1
Большой! Помогло ли это вам обоим? Если да, то можете ли вы пометить его как правильный ответ? Я был бы очень признателен: D
Джастин Варкентин
4
не используйте инструменты разработчика, когда используете только $ ('input [name = "q"]'). focus () или не работаете
Amitābha
12
Вау, я боролся с этим в течение нескольких месяцев, я только что увидел, что это вызвано тем, что консоль разработчика открыта. Мой всегда есть. Спасибо!
Алекс Турпин
20
+1 за «Вы не можете вызвать focus () для элемента, который не был присоединен к DOM». Кроме того, кажется, вы не можете вызвать это на скрытых элементах.
tandrewnichols
1
Использование setTimeoutдля решения проблем порядка операций делает огромной болью в поддержании патологии. Если обнаруживается ошибка, ее действительно сложно отладить. Куда бы вы ни вставляли элемент в DOM, он должен вызываться .focus()там.
Кевин Бил
55

Нашел решение в другом месте в сети ...

$('#id').focus();

не сработало.

$('#id').get(0).focus();

сделал работу.

Cymro
источник
4
Я проголосовал за это решение только потому, что оно сработало для меня, когда более популярное решение на этой странице не сработало. ;-)
chriv
Второй вариант, кажется, просто захватывает элемент dom и использует обычную версию javascript вместо версии jquery.
danielson317
7
Может быть, у вас есть несколько элементов с идентификатором «id» на вашей странице? В этом случае DOM не сломается, но вы также не можете назначить фокус нескольким элементам
DerpyNerd
Я обнаружил, что должен был сделать это с помощью window.setTimeout с задержкой 0, и тогда все хорошо. Спасибо. Все остальное, что я пробовал, провалилось в модале начальной загрузки.
Уэйд Хэтлер,
23

Некоторые ответы здесь предлагают использовать, setTimeoutчтобы задержать процесс фокусировки на целевом элементе. Один из них упоминает, что цель находится внутри модального диалога. Я не могу комментировать дальше о правильностиsetTimeout решения, не зная конкретных деталей того, где оно было использовано. Тем не менее, я подумал, что должен дать здесь ответ, чтобы выручить людей, которые сталкиваются с этой веткой, как и я

Простой факт в том, что вы не можете сосредоточиться на элементе, который еще не виден . Если вы столкнулись с этой проблемой, убедитесь, что цель действительно видна при попытке сфокусироваться на ней. В моем собственном случае я делал что-то подобное

$('#elementid').animate({left:0,duration:'slow'});
$('#elementid').focus();

Это не сработало. Я только понял , что происходит , когда я выполнил $ ( «# elementid»). Фокус () `из консоли , который сделал работу. Разница в том, что в моем коде над целью нет уверенности, что цель будет видимой, поскольку анимация может быть не завершена . И здесь кроется ключ

$('#elementid').animate({left:0,duration:'slow',complete:focusFunction});

function focusFunction(){$('#elementid').focus();}

работает так, как ожидалось. Я тоже изначально положил в setTimeoutрешение, и это тоже сработало. Однако произвольно выбранный тайм-аут неизбежно рано или поздно нарушит решение, в зависимости от того, насколько медленно ведущее устройство выполняет процесс, обеспечивающий видимость целевого элемента.

DroidOS
источник
Соответствующим намеком для меня было «убедиться, что цель действительно видна». это становится актуальным при попытке сфокусироваться на условно отображаемых элементах.
Чарли
Или когда элемент для фокусировки имеет visibility:hidden- он не будет сфокусирован.
Бакралл
«ты не можешь сосредоточиться на элементе, который еще не виден» - я люблю тебя. Просто добавив тайм-аут на 100 мс, я мог бы сфокусироваться на своем скрытом окне поиска. Спасибо!
Lubre
Остерегайтесь тайм-аутов. То, что работает на вашей машине разработки, может не работать на другой.
DroidOS
15

если вы используете bootstrap + модал, это работает для меня:

  $(myModal).modal('toggle');
  $(myModal).on('shown.bs.modal', function() {
    $('#modalSearchBox').focus()
  });
Wolf359
источник
8

Просто на тот случай, если кто-нибудь еще наткнется на этот вопрос и столкнется с той же ситуацией, что и я, - я пытался установить фокус после нажатия на другой элемент, но фокус, похоже, не работал. Оказывается, мне просто нужно e.preventDefault();- вот пример:

$('#recipients ul li').mousedown(function(e) {
    // add recipient to list
    ...
    // focus back onto the input
    $('#message_recipient_input').focus();
    // prevent the focus from leaving
    e.preventDefault();
});

Это помогло:

Если вы вызываете HTMLElement.focus () из обработчика событий mousedown, вы должны вызвать event.preventDefault (), чтобы фокус не покинул HTMLElement. Источник: https://developer.mozilla.org/en/docs/Web/API/HTMLElement/focus

Бен
источник
2
Работает только один! Триггер - это всплывающий элемент div, щелчок скрывает элемент div и помещает некоторое значение в текстовое поле (не нужно фокусироваться). Без protectDefault это текстовое поле всегда сфокусировано независимо от того, что -__-
rlatief
4

Я понимаю, что это старо, но наткнулся на это сегодня. Ни один из ответов не сработал для меня, я обнаружил, что сработало setTimeout. Я хотел, чтобы мой фокус был помещен во входную область модального окна, используя setTimeout сработало. Надеюсь это поможет!

user3861385
источник
Я тоже! И продолжительность тайм-аута действительно имела значение. Глупый ИП.
eaglei22
1
Но это не работает на мобильных устройствах. Мобильные браузеры в большинстве случаев игнорируют все, что находится внутри setTimeout
Kosmonaft
1
Как правило, использование setTimeoutявляется плохим решением. Вы не можете гарантировать время выполнения на компьютере пользователя, поэтому зависящие от времени вещи чрезвычайно хрупки.
Натан
3

У меня тоже была эта проблема. Решение, которое работало в моем случае, заключалось в использовании свойства tabindex элемента HTML.

Я использовал ng-repeatдля некоторых элементов li внутри списка, и я не смог перенести фокус на первый li с помощью .focus (), поэтому я просто добавил атрибут tabindex для каждого li во время цикла.

а сейчас <li ng-repeat="user in users track by $index" tabindex="{{$index+1}}"></li>

То, что +1 был индексом, начинается с 0. Также убедитесь, что элемент присутствует в DOM, прежде чем вызывать функцию .focus ().

Надеюсь, это поможет.

Кумар Шубхам
источник
2

Для тех, у кого проблема не работает, потому что вы использовали «$ (element) .show ()». Я решил это следующим образом:

 var textbox = $("#otherOption");
 textbox.show("fast", function () {
    textbox[0].focus();
  });

Так что вам не нужен таймер, он будет запущен после завершения метода show.

Роландо Ретана
источник
Это относится и к любому другому переходу: slideDown(), fadeIn()и т.д.
Альваро Гонсалесу
2

Добавьте задержку перед фокусировкой (). Достаточно 200 мс

function focusAndCursor(selector){
  var input = $(selector);
  setTimeout(function() {
    // this focus on last character if input isn't empty
    tmp = input.val(); input.focus().val("").blur().focus().val(tmp);
  }, 200);
}
Абель
источник
0

Если бы я снова столкнулся с этой проблемой, и, верьте или нет, все, что мне нужно было сделать, это закрыть инструменты разработчика. Видимо вкладка Консоль имеет приоритет фокуса над содержимым страницы.

aexl
источник
0

Убедитесь, что элемент и его родители видны. Вы не можете использовать фокус на скрытых элементах

mariovials
источник
-1

ДОПОЛНИТЕЛЬНОЕ РЕШЕНИЕ Была такая же проблема, когда focus (), похоже, не работал, но в итоге оказалось, что нужно было прокрутить до правильной позиции:

Мартин
источник
-1

Для моего случая я должен был указать индекс вкладки ( -1если только фокусируется через скрипт)

<div tabindex='-1'>
<!-- ... -->
</div>
Александр Добрикур
источник