Использование jQuery для проверки фокусировки ввода - PullRequest
534 голосов
/ 09 июня 2009

На первой странице сайта, который я создаю, несколько <div> используют псевдокласс CSS :hover, чтобы добавить границу, когда на них указывает мышь. Один из <div> s содержит <form>, который, используя jQuery, сохранит границу, если вход внутри него имеет фокус. Это работает отлично, за исключением того, что IE6 не поддерживает :hover на любых элементах, кроме <a> s. Итак, только для этого браузера мы используем jQuery для имитации CSS :hover с помощью метода $(#element).hover(). Единственная проблема заключается в том, что теперь, когда jQuery обрабатывает как focus() , так и hover(), когда ввод имеет фокус, тогда пользователь перемещает мышь внутрь и наружу, граница исчезает.

Я думал, что мы могли бы использовать какое-то условие, чтобы остановить это поведение. Например, если мы проверили при наведении мыши, фокусировался ли какой-либо из входов, мы могли бы остановить исчезновение границы. AFAIK, в jQuery нет селектора :focus, поэтому я не уверен, как это сделать. Есть идеи?

Ответы [ 15 ]

888 голосов
/ 21 апреля 2010

JQuery 1.6 +

jQuery добавил селектор :focus, поэтому нам больше не нужно добавлять его самостоятельно. Просто используйте $("..").is(":focus")

JQuery 1,5 и ниже

Редактировать: С течением времени мы находим лучшие методы для тестирования фокуса, новым фаворитом является это суть от Бена Алмана :

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

Цитируется из Матиаса Биненса здесь :

Обратите внимание, что добавлен тест (elem.type || elem.href) для фильтрации ложных срабатываний, таких как body. Таким образом, мы обязательно отфильтруем все элементы, кроме элементов управления формы и гиперссылок.

Вы определяете новый селектор. См. Плагины / Авторские . Тогда вы можете сделать:

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

или

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

Любой JQuery

Если вы просто хотите выяснить, какой элемент имеет фокус, вы можете использовать

$(document.activeElement)

Если вы не уверены, будет ли версия 1.6 или ниже, вы можете добавить селектор :focus, если он отсутствует:

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
43 голосов
/ 09 июня 2009

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
20 голосов
/ 22 марта 2011

Вот более надежный ответ, чем принятый в настоящее время:

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

Обратите внимание, что был добавлен тест (elem.type || elem.href) для фильтрации ложных срабатываний, таких как body. Таким образом, мы обязательно отфильтруем все элементы, кроме элементов управления формы и гиперссылок.

(взято из этой сущности Беном Алманом .)

13 голосов
/ 07 апреля 2015

Апрель 2015 Обновление

Поскольку этот вопрос уже давно и в игру вступили некоторые новые соглашения, я чувствую, что должен упомянуть, что метод .live устарел.

Вместо него теперь введен метод .on.

Их документация весьма полезна для объяснения того, как она работает;

Метод .on () присоединяет обработчики событий к текущему выбранному набору элементов в объекте jQuery. Начиная с jQuery 1.7, метод .on () предоставляет все функциональные возможности, необходимые для подключения обработчиков событий. За помощь в преобразовании из более старых методов событий jQuery, см. .bind (), .delegate () и .live ().

Итак, для того, чтобы вы нацелились на событие, ориентированное на ввод, вы можете использовать это в скрипте. Что-то вроде:

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

Это достаточно надежно и даже позволяет использовать клавишу TAB.

2 голосов
/ 09 июня 2009

Я не совсем уверен, что вы ищете, но похоже, что этого можно достичь, сохранив состояние входных элементов (или div?) В виде переменной:

$('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;
        });
});
1 голос
/ 30 октября 2014

, если кому-то все равно, есть лучший способ захватить фокус сейчас, $(foo).focus(...)

http://api.jquery.com/focus/

1 голос
/ 09 июня 2009

Альтернативой использованию классов для маркировки состояния элемента является внутренняя функциональность хранилища данных .

P.S .: Вы можете хранить логические значения и все, что пожелаете, используя функцию data(). Дело не только в строках:)

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

И тогда это просто вопрос доступа к состоянию элементов.

1 голос
/ 09 июня 2009

Задумывались ли вы об использовании mouseOver и mouseOut для имитации этого. Также посмотрите на mouseEnter и mouseLeave

0 голосов
/ 16 марта 2012

Простой

 <input type="text" /> 



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

    alert("I am in Focus");

     });
 </script>
0 голосов
/ 08 сентября 2011

У меня было событие .live ("focus"), установленное для выбора () (выделения) содержимого текстового ввода, чтобы пользователю не пришлось выбирать его перед вводом нового значения.

$ (formObj) .select ();

Из-за причуд между разными браузерами выбор иногда заменяется вызвавшим его щелчком, и он отменяет выбор содержимого сразу после размещения курсора в текстовом поле (в большинстве случаев в FF работает нормально, но в IE)

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

SetTimeout (функция () {$ (formObj) .select ();}, 200);

Это работало нормально, и выбор сохранялся, но возникала забавная проблема. Если вы переходите с одного поля на другое, фокус переключится на следующее поле до того, как произойдет выбор. Так как выбор крадет фокус, фокус затем возвращается и запускает новое событие «фокус». Это закончилось каскадом ввода, выбирающим танцы по всему экрану.

Реальным решением было бы проверить, что поле все еще имеет фокус, прежде чем выполнять select (), но, как уже упоминалось, нет простого способа проверить ... Я закончил тем, что просто обошелся без всякого автоматического выделения что должно быть одним вызовом jQuery select () в огромную функцию, загруженную подпрограммами ...

...