Нет наброски фокуса мыши, но все еще есть наброски фокуса на клавиатуре?
Когда элементы страницы имеют фокус (например, ссылку или кнопку), они показывают схему. Я бы хотел, чтобы этот контур отображался только тогда, когда этот элемент был задан с клавиатуры, а не мышью.
Можно ли определить, как этот элемент сосредоточился на JavaScript? Если да, то каким образом я могу управлять функцией выделения браузера?
Ответы
Ответ 1
Браузеры используют свойство CSS outline
, чтобы показать, какой элемент имеет фокус, как вы уже могли знать. Итак, в jQuery вы можете использовать:
$(document).ready(function() {
$("body").on("mousedown", "*", function(e) {
if (($(this).is(":focus") || $(this).is(e.target)) && $(this).css("outline-style") == "none") {
$(this).css("outline", "none").on("blur", function() {
$(this).off("blur").css("outline", "");
});
}
});
});
Объяснение: Эта функция ищет событие mousedown
для любого элемента. Это событие делегировано, то есть оно будет применяться к элементам, находящимся на этой странице, а также к динамическим изменениям в будущем. Когда щелчок мыши над элементом, его свойство CSS outline
установлено на none
; контур удаляется.
Целевой элемент получает новый обработчик для blur
. Когда фокус берется из элемента, свойство outline
задается пустой строкой (это удаляет его из атрибута style
), позволяя браузеру снова управлять контуром. Затем элемент удаляет свой собственный обработчик blur
для освобождения памяти. Таким образом, элемент выделяется только при фокусировке с клавиатуры.
Изменить
Основываясь на комментариях Ракеша ниже, я сделал небольшое изменение. Теперь функция может определить, существует ли уже набор outline
, и избежать его переопределения. Демо здесь.
Ответ 2
http://jsfiddle.net/np3FE/2/
$(function(){
var lastKey = new Date(),
lastClick = new Date();
$(document).on( "focusin", function(e){
$(".non-keyboard-outline").removeClass("non-keyboard-outline");
var wasByKeyboard = lastClick < lastKey
if( wasByKeyboard ) {
$( e.target ).addClass( "non-keyboard-outline");
}
});
$(document).on( "click", function(){
lastClick = new Date();
});
$(document).on( "keydown", function() {
lastKey = new Date();
});
});
CSS
*:active, *:focus {
outline: none;
}
*:active.non-keyboard-outline, *:focus.non-keyboard-outline {
outline: red auto 5px;
}
Ответ 3
Один простой способ, который я вижу, - использовать событие мыши для предотвращения фокуса.
$('#element').click(function(){
$(this).blur();
});
Это приводит к потенциальной проблеме, что вы не сможете использовать мышь, чтобы выбрать элемент вообще. Таким образом, вы можете просто добавить класс и настроить стиль фокуса.
$('#element').click(function(){
$(this).addClass('fromMouse');
});
$('#element').blur(function(){
if($(this).hasClass('fromMouse'){
$(this).removeClass('fromMouse');
}
});
CSS
.fromMouse{
outline: none;
}
http://api.jquery.com/blur/
Ответ 4
CSS
:focus{
outline: none;
}
.outline{
outline: 2px solid rgba(200,120,120, 0.8);
}
Код jQuery
$(function(){
$('*').on('keydown.tab', function(e){
/*
TAB or Shift Tab, Aw.
Add some more key code if you really want
*/
if ( 9== e.which && this == e.target ){
window.setTimeout( function(){
$('.outline').removeClass('outline');
$(document.activeElement).addClass('outline');
}, 100 );
}
});
});
Это прекрасно работает. Вы получите контур только тогда, когда элемент будет сфокусирован с помощью Keyboard (я знаю только Tab и Shift Tab, вы можете добавить больше)
Посмотрите, как работает:
http://jsbin.com/okarez/1
Ответ 5
Основываясь на ответе @theftprevention, более настраиваемое решение может быть:
$(function(){
$('body')
.on('focus', '*', function() {
var e = $(this);
if (!e.is('.focus-mouse')) {
e.addClass('focus-keyboard');
}
})
.on('mousedown', '*', function() {
$(this).removeClass('focus-keyboard').addClass('focus-mouse');
})
.on('blur', '*', function() {
$(this).removeClass('focus-keyboard').removeClass('focus-mouse');
});
});
Теперь вам просто нужно вырезать, используя классы .focus-keyboard и .focus-mouse в CSS.
.focus-keyboard{
background:#eeeeee;
}
.focus-mouse{
outline: 0;
}