Нет наброски фокуса мыши, но все еще есть наброски фокуса на клавиатуре?

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

Можно ли определить, как этот элемент сосредоточился на 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;
}