Używanie jQuery do testowania, czy wejście ma fokus

Na pierwszej stronie strony, którą buduję, kilka <div>używa pseudo-klasy CSS :hover, aby dodać obramowanie, gdy mysz jest nad nimi. Jeden z <div>zawiera <form>, który, używając jQuery, zachowa obramowanie, jeśli Dane wejściowe wewnątrz niego mają fokus. Działa to doskonale, z wyjątkiem tego, że IE6 nie obsługuje :hover na żadnych elementach innych niż <a> s. więc tylko dla tej przeglądarki używamy jQuery do naśladowania CSS :hover przy użyciu metody $(#element).hover(). Jedynym problemem jest to, że teraz jQuery obsługuje zarówno formularz focus() oraz hover(), gdy wejście ma fokus, a następnie użytkownik przesuwa mysz w I Na Zewnątrz, granica znika.

Pomyślałem, że moglibyśmy użyć jakiegoś warunku, aby powstrzymać to zachowanie. Na przykład, jeśli Przetestowaliśmy na mysz, jeśli któreś z wejść miało fokus, moglibyśmy zatrzymać odejście granicy. AFAIK, w jQuery nie ma selektora :focus, więc nie wiem jak to zrobić. Jakieś pomysły?

Author: Michał Perłakowski, 2009-06-09

15 answers

JQuery 1.6 +

JQuery dodał a :focus selektor więc nie musimy już dodawać go sami. Wystarczy użyć $("..").is(":focus")

JQuery 1.5 i poniżej

Edit: wraz ze zmianą czasu znajdujemy lepsze metody testowania ostrości, nowym faworytem jest ten gist z Ben Alman :

jQuery.expr[':'].focus = function( elem ) {
  return elem === document.activeElement && ( elem.type || elem.href );
};

Cytat z Mathiasa Bynensa tutaj :

Zauważ, że test (elem.type || elem.href) został dodany, aby odfiltrować fałszywe wyniki, takie jak ciało. W ten sposób upewniamy się, że aby odfiltrować wszystkie elementy z wyjątkiem kontrolek formularza i hiperłączy.

Definiujesz nowy selektor. Zobacz Pluginy / Authoring . Wtedy możesz zrobić:

if ($("...").is(":focus")) {
  ...
}

Lub:

$("input:focus").doStuff();

Dowolny jQuery

Jeśli chcesz dowiedzieć się, który element ma focus, możesz użyć

$(document.activeElement)

Jeśli nie jesteś pewien, czy wersja będzie 1.6 lub niższa, możesz dodać selektor :focus jeśli go brakuje:

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
 860
Author: gnarf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:05

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
 44
Author: Daniel Moura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 15:22:11

Oto bardziej solidna odpowiedź niż obecnie akceptowana:

jQuery.expr[':'].focus = function(elem) {
  return elem === document.activeElement && (elem.type || elem.href);
};

Zauważ, że test (elem.type || elem.href) został dodany do filtrowania fałszywych wyników, takich jak body. W ten sposób upewniamy się, że odfiltrowujemy wszystkie elementy oprócz kontrolek formularza i hiperłączy.

(zaczerpnięte ztego gist przezBen Alman .)

 19
Author: Mathias Bynens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-22 12:58:29

Kwiecień 2015 Aktualizacja

Ponieważ to pytanie istnieje już jakiś czas, a niektóre nowe konwencje weszły w grę, czuję, że powinienem wspomnieć, że metoda .live została zdeprecjonowana.

W jej miejsce wprowadzono metodę .on.

Ich Dokumentacja jest bardzo przydatna w wyjaśnieniu, jak to działa;

The .metoda on () dołącza procedury obsługi zdarzeń do aktualnie wybranego zestawu elementów w obiekcie jQuery. Od jQuery 1.7, .metoda on () zapewnia wszystkie funkcje wymagane do dołączania programów obsługi zdarzeń. Na pomoc w konwersji ze starszych metod zdarzeń jQuery, zobacz .bind(), .delegat (), oraz .live ().

Więc, aby celować w Zdarzenie "input focused", możesz użyć tego w skrypcie. Coś w stylu:

$('input').on("focus", function(){
   //do some stuff
});

Jest to dość solidne, a nawet pozwala na użycie klawisza TAB.

 13
Author: jbutler483,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-08 17:36:51

Nie jestem do końca pewien, o co ci chodzi, ale wygląda na to, że można to osiągnąć zapisując stan elementów wejściowych (lub div?) jako zmienna:

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});
 2
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 21:37:31

Alternatywą dla używania klas do oznaczania stanu elementu jest wewnętrzna funkcja przechowywania danych .

P. S.: za pomocą funkcji data() możesz przechowywać booleany i cokolwiek zechcesz. Nie chodzi tylko o struny:)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

I wtedy jest to tylko kwestia dostępu do stanu elementów.

 1
Author: cllpse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-09 11:30:07

Czy myślałeś o użyciu mouseOver i mouseOut do symulowania tego. Zobacz też mouseEnter i mouseLeave

 1
Author: mkoryak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 06:23:06

Śledź oba stany (najechane, skupione) jako flagi true/false, a za każdym razem, gdy jeden się zmieni, uruchom funkcję, która usuwa obramowanie, jeśli oba są fałszywe, w przeciwnym razie pokazuje obramowanie.

Tak: onfocus ustawia focus = true, onblur ustawia focus = false. onmouseover ustawia hovered = true, onmouseout ustawia hovered = false. Po każdym z tych zdarzeń uruchom funkcję, która dodaje / usuwa obramowanie.

 0
Author: Blixt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 21:35:40

Z tego co wiem, nie można zapytać przeglądarki, czy jakieś wejście na ekranie ma fokus, trzeba ustawić jakiś rodzaj śledzenia ostrości.

Zwykle mam zmienną o nazwie "noFocus" i ustawiam ją na true. Następnie dodaję Zdarzenie focus do wszystkich wejść, które powoduje, że noFocus jest fałszywy. Następnie dodaję Zdarzenie blur do wszystkich wejść, które ustawiają noFocus z powrotem na true.

Mam klasę MooTools, która radzi sobie z tym dość łatwo, jestem pewien, że możesz utworzyć wtyczkę jquery, aby zrobić to samo.

Once that ' s utworzony, możesz sprawdzić noFocus przed wykonaniem jakiejkolwiek wymiany obramowania.

 0
Author: Ryan Florence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 21:36:40

Nie ma :focus, ale jest :selected http://docs.jquery.com/Selectors/selected

Ale jeśli chcesz zmienić wygląd rzeczy na podstawie tego, co jest zaznaczone, prawdopodobnie powinieneś pracować ze zdarzeniami rozmycia.

Http://docs.jquery.com/Events/blur

 0
Author: Chris Brandsma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 21:38:14

Istnieje plugin do sprawdzenia czy Element jest skupiony: http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
 0
Author: Murat Çorlu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-12 09:05:16

Miałem .Zdarzenie live ("focus") ustawione na select () (highlight) zawartość wejścia tekstu, tak aby użytkownik nie musiał go wybierać przed wpisaniem nowej wartości.

$(formObj).select ();

Z powodu dziwactw między różnymi przeglądarkami, select czasami był zastępowany przez kliknięcie, które go spowodowało, i usuwał zaznaczenie zawartości zaraz po umieszczeniu kursora w polu tekstowym (działał głównie ok w FF, ale nie w IE)

I thought I could Rozwiąż to, umieszczając niewielkie opóźnienie na select...

SetTimeout (function () {$(formObj).wybierz();},200);

To działało dobrze i select będzie trwał, ale pojawił się zabawny problem.. Jeśli Zakładka z jednego pola do następnego, fokus przełączy się na następne pole przed dokonaniem wyboru. Ponieważ opcja select wykrada fokus, fokus powróci i uruchomi nowe zdarzenie "fokus". Skończyło się to kaskadą wejść, które tańczą po całym ekranie.

A wykonalnym rozwiązaniem byłoby sprawdzenie, czy pole nadal ma focus przed wykonaniem select (), ale jak wspomniano, nie ma prostego sposobu na sprawdzenie... Skończyło się na tym, że zrezygnowałem z całego automatycznego podświetlania, zamiast zamieniać to, co powinno być pojedynczym wywołaniem jQuery select() w ogromną funkcję z podprogramami...

 0
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-08 19:56:19

Jeśli kogoś to obchodzi, jest o wiele lepszy sposób na uchwycenie ostrości, $(foo).focus(...)

Http://api.jquery.com/focus/

 0
Author: CrackSmoker9000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-30 04:13:17

To, co zrobiłem, to stworzenie dowolnej klasy o nazwie .elementhasfocus, który jest dodawany i usuwany w funkcji jQuery focus (). Gdy funkcja hover() uruchomi się po wyłączeniu myszy, sprawdza, czy jest .elementhasfocus:

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

Więc jeśli nie ma tej klasy (Czytaj: żadne elementy w div nie mają Fokusa) obramowanie jest usuwane. Inaczej nic się nie stanie.

 0
Author: bloudermilk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-26 20:28:57

Proste

 <input type="text" /> 



 <script>
     $("input").focusin(function() {

    alert("I am in Focus");

     });
 </script>
 -1
Author: Code Spy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-16 07:28:22