На первой странице сайта, который я создаю, несколько <div>
используют псевдокласс класса CSS :hover
, чтобы добавить границу, когда мышь над ними. Один из <div>
содержит <form>
, который, используя jQuery, будет удерживать границу, если вход в нее имеет фокус. Это прекрасно работает, за исключением того, что IE6 не поддерживает :hover
для любых элементов, кроме <a>
s. Итак, для этого браузера мы используем jQuery для имитации CSS :hover
с помощью метода $(#element).hover()
. Единственная проблема заключается в том, что теперь jQuery обрабатывает как форму focus()
, так и hover()
, когда вход имеет фокус, тогда пользователь перемещает мышь туда и обратно, граница уходит.
Я думал, что мы можем использовать какое-то условное условие, чтобы остановить это поведение. Например, если мы проверили мышь, если какой-либо из входов был в фокусе, мы могли бы остановить границу от прохода. AFAIK, нет селектора :focus
в jQuery, поэтому я не уверен, как это сделать. Любые идеи?
jQuery добавил селектор :focus
, поэтому нам больше не нужно его добавлять. Просто используйте $("..").is(":focus")
Изменить: По мере изменения мы находим лучшие методы тестирования фокуса, новый фаворит этот смысл из Ben Alman:
jQuery.expr[':'].focus = function( elem ) {
return elem === document.activeElement && ( elem.type || elem.href );
};
Цитата из Mathias Bynens здесь:
Обратите внимание, что тест
(elem.type || elem.href)
был добавлен для фильтрации ложных срабатываний, таких как тело. Таким образом, мы должны отфильтровать все элементы, кроме элементов управления формой и гиперссылок.
Вы определяете новый селектор. См. Plugins/Authoring. Затем вы можете сделать:
if ($("...").is(":focus")) {
...
}
или
$("input:focus").doStuff();
Если вы просто хотите выяснить, какой элемент имеет фокус, вы можете использовать
$(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 );
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)
был добавлен для фильтрации ложных срабатываний, таких как body
. Таким образом, мы должны отфильтровать все элементы, кроме элементов управления формой и гиперссылок.
(взято из этот смысл Бен Альман. )
Поскольку этот вопрос был довольно долгое время, и некоторые новые соглашения вступили в игру, я чувствую, что я должен упомянуть, что метод .live
был обесценен.
Вместо этого теперь был введен метод .on
.
Их документация весьма полезна для объяснения того, как она работает;
Метод .on() присоединяет обработчики событий к выбранному в данный момент набору элементов в объекте jQuery. Начиная с jQuery 1.7, метод .on() предоставляет все функции, необходимые для присоединения обработчиков событий. Для помощь в преобразовании из более старых методов события jQuery, см..bind(),.delegate() и .live().
Итак, для того, чтобы настроить таргетинг на событие, ориентированное на вход, вы можете использовать его в script. Что-то вроде:
$('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;
});
});
Альтернативой использованию классов для обозначения состояния элемента является внутренняя функция хранилища данных.
P.S.: Вы можете сохранять логические значения и все, что хотите, используя функцию data()
. Это не только строки:)
$("...").mouseover(function ()
{
// store state on element
}).mouseout(function ()
{
// remove stored state on element
});
И тогда это просто вопрос доступа к состоянию элементов.
Вы думали об использовании mouseOver и mouseOut для имитации этого. Также загляните в mouseEnter и mouseLeave
Если кто-то заботится, теперь гораздо лучший способ захватить фокус, $(foo).focus(...)
Простой
<input type="text" />
<script>
$("input").focusin(function() {
alert("I am in Focus");
});
</script>
У меня было событие .live( "focus" ), чтобы выбрать() (выделить) содержимое текстового ввода, чтобы пользователь не должен был выбирать его, прежде чем вводить новое значение.
$(formObj).select();
Из-за причуд между различными браузерами выбор иногда заменяется щелчком, который вызвал его, и он отменил выбор содержимого сразу после того, как он помещал курсор в текстовое поле (работал в основном в FF, но не удался IE)
Я думал, что смогу это решить, слегка отложив выбор...
SetTimeout (функция() {$ (formObj).select();}, 200);
Это сработало отлично, и выбор сохранится, но возникла смешная проблема. Если вы вложили вкладку из одного поля в другое, фокус переключился бы на следующее поле до того, как будет выбран выбор. После выбора фокуса фокуса фокус будет возвращаться назад и запускать новое событие "фокус". Это оказалось в каскаде ввода, который выбирает танцы по всему экрану.
Работоспособным решением будет проверка того, что поле все еще имеет фокус перед выполнением select(), но, как уже упоминалось, нет простого способа проверить... Я в итоге просто отказался от всего автоматического выделения, а не поворачивал что должно быть единственным вызовом jQuery select() в огромную функцию, загруженную с помощью подпрограмм...
Существует плагин для проверки фокусировки элемента: http://plugins.jquery.com/project/focused
$('input').each(function(){
if ($(this) == $.focused()) {
$(this).addClass('focused');
}
})
Нет: фокус, но есть: selected http://docs.jquery.com/Selectors/selected
но если вы хотите изменить то, как все выглядит на основе выбранного, вы, вероятно, должны работать с событиями размытия.
Следите за тем, чтобы оба состояния (зависающие, сфокусированные) были как флагов истина/ложь, и всякий раз, когда они меняются, запускайте функцию, которая удаляет границу, если оба они ложны, в противном случае отображается граница.
Итак: onfocus устанавливает focus = true, onblur устанавливает focus = false. onmouseover устанавливает hovered = true, onmouseout устанавливает hovered = false. После каждого из этих событий запускается функция, которая добавляет/удаляет границу.
Что я сделал, это создать произвольный класс с именем .elementhasfocus, который добавляется и удаляется в функции jQuery focus(). Когда функция hover() работает от мыши, она проверяет .elementhasfocus:
if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");
Итак, если у него нет этого класса (читай: ни один элемент в div не имеет фокуса), граница будет удалена. В противном случае ничего не происходит.
Насколько я знаю, вы не можете запрашивать браузер, если какой-либо ввод на экране имеет фокус, вам нужно настроить какое-то отслеживание фокуса.
Обычно я имею переменную под названием "noFocus" и устанавливаю ее в true. Затем я добавляю событие фокусировки ко всем входам, которые делают noFocus false. Затем я добавляю событие размытия ко всем входам, которые возвращают noFocus в true.
У меня есть класс MooTools, который обрабатывает это довольно легко, я уверен, что вы можете создать плагин jquery, чтобы сделать то же самое.
Как только это будет создано, вы можете сделать check noFocus перед тем, как выполнить обмен границ.