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

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

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

15 ответов


jQuery 1.6+

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

в jQuery 1.5 и ниже

Edit: как раз изменение, мы находим более лучшие методы для испытывать фокус, новый фаворит это суть от Бена Альмана:

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

цитата из Матиаса Байненса здесь:

отметим, что


CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

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

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

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

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

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


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

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

в месте .on метод уже внедрен.

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

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

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

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

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


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

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

С. П.: Вы можете хранить переключатели и все, что вы желаете с помощью


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


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

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


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

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

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

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


нет: фокус, но есть: выбрано http://docs.jquery.com/Selectors/selected

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

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


есть плагин, чтобы проверить, если элемент сосредоточен:http://plugins.jquery.com/project/focused

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

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

$(formObj).select ();

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

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

setTimeout (function () {$(formObj).выберите();},200);

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

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


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

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


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

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

поэтому, если у него нет этого класса (чтение: никакие элементы в div не имеют фокуса), граница удаляется. Иначе ничего не случится.


простой

 <input type="text" /> 



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

    alert("I am in Focus");

     });
 </script>