it-swarm.com.ru

Использование jQuery для проверки фокусировки ввода

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

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

534
bloudermilk

jQuery 1.6+

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

jQuery 1,5 и ниже

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

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 );
887
gnarf

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
43
Daniel Moura

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

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

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

(Взято из эта сутьБен Алман .)

20
Mathias Bynens

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

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

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

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

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

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

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

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

13
jbutler483

Я не совсем уверен, что вы после, но это звучит так, как будто это может быть достигнуто путем сохранения состояния элементов ввода (или 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;
        });
});
2
James

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

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

1
CrackSmoker9000

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

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

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

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

1
cllpse

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

1
mkoryak

В итоге я создал произвольный класс с именем .elementhasfocus, который добавляется и удаляется в функции jQuery focus (). Когда функция hover () запускается при наведении мыши, она проверяет наличие .elementhasfocus:

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

Поэтому, если у него нет этого класса (читай: ни один элемент внутри div не имеет фокуса), граница удаляется. В противном случае ничего не происходит.

0
bloudermilk

Существует плагин для проверки того, что элемент сфокусирован: http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
0
Murat Çorlu

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

$ (FormObj) .select ();

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

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

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

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

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

0
Brian

Следите за обоими состояниями (hovered, focus) как за флагами true/false, и всякий раз, когда один из них изменяется, запускайте функцию, которая удаляет рамку, если оба имеют значение false, в противном случае показывает рамку.

Итак: наборы onfocus focus = true, наборы onflur focus = false. onmouseover устанавливает hovered = true, onmouseout устанавливает hovered = false. После каждого из этих событий запускается функция, которая добавляет/удаляет границу.

0
Blixt

Насколько я знаю, вы не можете спросить браузер, фокусируется ли какой-либо ввод на экране, вам нужно настроить какое-то отслеживание фокуса.

У меня обычно есть переменная с именем "noFocus" и она имеет значение true. Затем я добавляю событие фокуса ко всем входам, что делает noFocus ложным. Затем я добавляю событие размытия ко всем входам, которые возвращают noFocus значение true.

У меня есть класс MooTools, который обрабатывает это довольно легко, я уверен, что вы могли бы создать плагин jquery, чтобы сделать то же самое.

После того, как это будет создано, вы можете проверить noFocus перед любой заменой границ.

0
Ryan Florence

Нет: focus, но есть: selected http://docs.jquery.com/Selectors/selected

но если вы хотите изменить то, как все выглядит в зависимости от того, что вы выбрали, вы, вероятно, должны работать с событиями размытия.

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

0
Chris Brandsma