$ .focus () nie działa

155

Ostatnim przykładem jQuery w focus()dokumentacji państw

$('#id').focus()

powinien sprawić, że wejście będzie skoncentrowane (aktywne). Nie wydaje mi się, żeby to działało.

Nawet w konsoli na tej stronie próbuję ją znaleźć w polu wyszukiwania

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

i nic nie dostaję. Jakieś pomysły?

Sam Selikoff
źródło
2
Czy możesz pokazać nam swój kod?
Adil,
Będziemy musieli wiedzieć więcej, ponieważ dla mnie działa dobrze: jsfiddle.net/G7hwR/1 po prostu kliknij w dowolnym miejscu na prawym panelu i skupi się ...
Rob G
Czy jednak skupienie się na tej stronie nie powinno działać? Fragment, który podałem?
Sam Selikoff,
To zależy od tego, w czym jest zawarty; jeśli nie ma go w środku, prawdopodobnie zostanie uruchomiony, zanim strona jeszcze się wyrenderuje ...
Rob G,
Dla tych, którzy przychodzą tu z wyszukiwarki: wbudowane w przeglądarkę narzędzia programistyczne mogą kolidować z funkcjonalnością focus(). Więcej informacji
aexl

Odpowiedzi:

392

Właściwie przykład, który podałeś, aby skupić się na tej stronie, działa dobrze, o ile nie jesteś skupiony na konsoli. Powodem, dla którego to nie działa, jest po prostu to, że nie kradnie ostrości z konsoli programisty. Jeśli uruchomisz następujący kod w konsoli, a następnie szybko klikniesz w oknie przeglądarki, zobaczysz, że ustawia on pole wyszukiwania:

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

Co do twojego drugiego, jedyną rzeczą, która sprawiała mi kłopoty w przeszłości, jest kolejność wydarzeń. Nie możesz wywołać focus () na elemencie, który nie został dołączony do DOM. Czy element, na którym chcesz się skupić, został już dołączony do DOM?

Justin Warkentin
źródło
1
Wspaniały! Czy to pomogło w obu twoich problemach? Jeśli tak, czy możesz oznaczyć to jako poprawną odpowiedź? Byłbym bardzo wdzięczny: D
Justin Warkentin,
4
nie używaj narzędzi programistycznych, gdy używasz tylko $ ('input [name = "q"]'). focus (); lub nie działa
Amitābha,
12
Wow, zmagałem się z tym od miesięcy, dopiero zobaczyłem, że jest to spowodowane otwarciem konsoli programisty. Mój zawsze jest. Dziękuję Ci!
Alex Turpin
20
+1 dla „Nie możesz wywołać focus () na elemencie, który nie został dołączony do DOM”. Wygląda też na to, że nie można tego wywołać na ukrytych elementach.
tandrewnichols
1
Używanie setTimeoutdo rozwiązywania problemów związanych z kolejnością operacji sprawia, że ​​utrzymanie ich jest ogromnym utrapieniem. Jeśli pojawi się błąd, to naprawdę trudno go debugować. Gdziekolwiek wstawiasz element do DOM, powinien .focus()tam zadzwonić .
Kevin Beal
55

Znalazłem rozwiązanie w innym miejscu w sieci ...

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

nie działał.

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

zadziałało.

Cymro
źródło
4
Głosowałem za tym rozwiązaniem tylko dlatego, że zadziałało u mnie, podczas gdy bardziej popularne rozwiązanie na tej stronie nie. ;-)
chriv
Wydaje się, że drugą opcją jest po prostu pobranie elementu dom i użycie zwykłej wersji javascript zamiast wersji jquery.
danielson317
7
Czy to możliwe, że masz na swojej stronie wiele elementów o identyfikatorze „id”? DOM nie
zepsuje się
Okazało się, że muszę to zrobić za pomocą window.setTimeout z opóźnieniem 0, a potem wszystko jest w porządku. Dzięki. Wszystko inne, czego próbowałem, zawiodło w trybie bootstrap.
Wade Hatler
23

Niektóre z odpowiedzi sugerują użycie w setTimeoutcelu opóźnienia procesu skupiania się na elemencie docelowym. Jeden z nich wspomina, że ​​cel znajduje się wewnątrz okna dialogowego. Nie mogę dalej komentować poprawności setTimeoutrozwiązania, nie znając szczegółowych informacji, gdzie zostało użyte. Pomyślałem jednak, że powinienem udzielić tutaj odpowiedzi, aby pomóc ludziom, którzy natkną się na ten wątek, tak jak ja

Prosty fakt jest taki , że nie możesz skupić się na elemencie, który nie jest jeszcze widoczny . Jeśli napotkasz ten problem, upewnij się, że cel jest rzeczywiście widoczny podczas próby skupienia się na nim. W moim przypadku robiłem coś podobnego

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

To nie zadziałało. Ja tylko sobie sprawę, co się dzieje, kiedy wykonywane $ ( „# elementid”). Ostrości () `z konsoli, który zrobił pracę. Różnica - w moim kodzie nad celem nie ma pewności, że cel faktycznie będzie widoczny, ponieważ animacja może nie być kompletna . I tu jest wskazówka

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

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

działa zgodnie z oczekiwaniami. Ja też początkowo wprowadziłem setTimeoutrozwiązanie i też zadziałało. Jednak arbitralnie wybrany limit czasu z pewnością zepsuje rozwiązanie wcześniej lub później, w zależności od tego, jak wolno urządzenie hosta wykonuje proces zapewniania, że ​​element docelowy jest widoczny.

DroidOS
źródło
Istotną wskazówką dla mnie było „upewnij się, że cel jest rzeczywiście widoczny”. staje się to istotne przy próbie skupienia się na elementach renderowanych warunkowo.
charlie Carver
Lub gdy element do skupienia ma visibility:hidden- nie zostanie skupiony.
bakrall
„nie możesz skupić się na elemencie, którego jeszcze nie widać” - kocham cię. Po prostu dodając limit czasu 100 ms, mogłem wywołać fokus na moim ukrytym polu wyszukiwania. Dzięki!
LuBre
Uważaj na przekroczenia czasu. To, co działa na twoim komputerze deweloperskim, może nie działać na innym.
DroidOS
15

jeśli używasz bootstrap + modal, to zadziałało dla mnie:

  $(myModal).modal('toggle');
  $(myModal).on('shown.bs.modal', function() {
    $('#modalSearchBox').focus()
  });
Wolf359
źródło
8

Na wypadek gdyby ktoś inny natknął się na to pytanie i miał taką samą sytuację jak ja - próbowałem ustawić fokus po kliknięciu na inny element, ale fokus nie wydawał się działać. Okazuje się, że potrzebowałem tylko e.preventDefault();- oto przykład:

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

Pomogło to:

Jeśli wywołujesz HTMLElement.focus () z modułu obsługi zdarzeń mousedown, musisz wywołać event.preventDefault (), aby fokus nie opuszczał HTMLElement. Źródło: https://developer.mozilla.org/en/docs/Web/API/HTMLElement/focus

Ben
źródło
2
Tylko jeden działa! Wyzwalacz to wyskakujący element div, kliknięcie ukrywa element div i umieszcza pewną wartość w polu tekstowym (nie tę, która ma być fokusem). Bez zapobieganiaDefault, to pole tekstowe jest zawsze skoncentrowane bez względu na wszystko -__-
rlatief
4

Zdaję sobie sprawę, że to jest stare, ale natrafiłem na to dzisiaj. Żadna z odpowiedzi nie zadziałała dla mnie, ale okazało się, że zadziałało, to ustawiony czas. Chciałem, aby skupiłem się na polu wejściowym modalu, używając setTimeout działał. Mam nadzieję że to pomoże!

user3861385
źródło
Ja też! ORAZ długość limitu czasu naprawdę zrobiła różnicę. Głupi IE.
eaglei 22
1
Ale to nie działa na urządzeniach mobilnych. Przeglądarki mobilne w większości przypadków ignorują wszystko, co jest w środku setTimeout
Kosmonaft
1
Z reguły używanie setTimeoutjest złym rozwiązaniem. Nie możesz zagwarantować czasu wykonania na komputerze użytkownika, więc rzeczy zależne od czasu są niezwykle delikatne.
Nathan,
3

Ja też miałem ten problem. Rozwiązaniem, które zadziałało w moim przypadku, było użycie właściwości tabindex w elemencie HTML.

I był przy użyciu ng-repeatniektórych elementów li wewnątrz listy, a ja nie byłem w stanie przynieść ostrość na pierwszym li użyciu .focus (), więc po prostu dodaje się do każdego atrybutu tabindex li podczas pętli.

więc teraz <li ng-repeat="user in users track by $index" tabindex="{{$index+1}}"></li>

To +1 było indeksem zaczynającym się od 0. Upewnij się również, że element jest obecny w DOM przed wywołaniem funkcji .focus ()

Mam nadzieję, że to pomoże.

Kumar Shubham
źródło
2

Dla tych, którzy mają problem z niedziałaniem, ponieważ użyłeś "$ (element) .show ()". Rozwiązałem to w następujący sposób:

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

Więc nie potrzebujesz licznika czasu, zostanie on wykonany po zakończeniu metody show.

Rolando Retana
źródło
Odnosi się to do każdej innej transformacji: slideDown(), fadeIn()itp
Alvaro Gonzalez
2

Dodaj opóźnienie przed aktywowaniem (). 200 ms wystarczy

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);
}
Abel
źródło
0

Miałem ten problem ponownie teraz i wierz lub nie, wszystko, co musiałem zrobić, to zamknąć narzędzia programistyczne. Najwyraźniej zakładka Console ma pierwszeństwo przed zawartością strony.

aexl
źródło
0

Upewnij się, że element i jego elementy nadrzędne są widoczne. Nie możesz skupić się na ukrytych elementach

mariovials
źródło
-1

DODATKOWE ROZWIĄZANIE Wystąpił ten sam problem, w którym funkcja focus () wydawała się nie działać, ale ostatecznie okazało się, że potrzebne było przewijanie do właściwej pozycji:

Jaskółka oknówka
źródło
-1

W moim przypadku musiałem określić indeks zakładki ( -1jeśli można go ustawić tylko za pomocą skryptu)

<div tabindex='-1'>
<!-- ... -->
</div>
Alexandre Daubricourt
źródło