问题 鼠标焦点没有轮廓,但仍然有键盘焦点的轮廓?


当页面元素具有焦点(例如链接或按钮)时,它们会显示轮廓。我希望这个轮廓只显示当该元素由键盘而不是鼠标给定焦点时。

是否有可能确定该元素如何通过JavaScript获得关注?如果是这样,我如何控制浏览器自己的概述功能?


10727
2017-08-01 16:54


起源

如果你不知道从哪里开始,你可以看看CSS。仅向输入元素添加css并查看其工作原理。之后,您可以按照自己想要的方式做一些更有趣的事情。 - wendelbsilva


答案:


浏览器使用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 property设置为空字符串(这会将其从元素中删除 style 属性),允许浏览器再次控制轮廓。然后,元素删除它自己的 blur 释放内存的处理程序。这样,只有在从键盘聚焦时才会勾勒出元素。

编辑

根据拉克什在下面的评论,我做了一个小小的改变。该功能现在可以检测是否已有 outline 设置,并将避免覆盖它。 在这里演示。


11
2017-08-01 17:34



按照代码我想如果我的html中有一些元素我使用的是大纲,这段代码将永远删除它。 - Rakesh Juyal
你用我发布的小提琴测试了吗?因为 blur 处理程序负责这一点。当焦点丢失在元素上时,它就会失去焦点 outline 被jQuery的一个特殊功能删除 css()。设置为空字符串时,将从元素中删除CSS属性 style 属性,如果它在那里。自元素以来 style 属性具有最高优先级,然后当从该属性中删除属性时,它的属性 outline 将恢复到之前定义的位置。 - theftprevention
是的,我试过你的jsfiddle。请参阅我添加了一个带默认大纲的div。点击它一次,它的轮廓永远消失。 jsfiddle.net/RuHNW/1 - Rakesh Juyal
啊,我明白你的意思了。我修改了 小提琴 并编辑了我的答案。看看这对你有用,谢谢! - theftprevention
这对我有用,我正在寻找一种方法来做这件事......投了票。 - skyline33


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
2017-08-01 17:38



+1为唯一的lastClick和lastKey事物。但它看起来有点太长了。 - Rakesh Juyal
@RakeshJuyal通过删除空格和合并事件可以缩短它,但这并不意味着它会更具可读性或更好:P - Esailija
最后一次点击和关键的事情似乎是解决这个问题的好方法。但你需要挂钩 mousedown 事件而不是 click 让它更好地工作(至少在Chrome中)。 - Qtax


我能看到的一个简单方法是使用鼠标事件来防止焦点被触发。

$('#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/


1
2017-08-01 17:35





删除 outline 可访问性很糟糕!理想情况下,聚焦环仅在用户出现时显示 打算用键盘

2018答案: 使用 :焦点可见。它目前是一个W3C提议,用于使用CSS设置仅键盘焦点的样式。在主流浏览器支持之前,您可以使用这种强大的功能 填充工具。它不需要添加额外的元素或改变 tabindex

/* Remove outline for non-keyboard :focus */
*:focus:not(.focus-visible) {
  outline: none;
}

/* Optional: Customize .focus-visible */
.focus-visible {
  outline-color: lightgreen;
}

我也写了更详细的内容 岗位 有一些演示,以防您需要更多信息。


1
2018-05-28 17:26





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 );
    }

  });

});

这很好用。只有在使用键盘聚焦元素时才能获得轮廓(我只知道Tab和Shift Tab,但你可以添加更多)

看它工作: http://jsbin.com/okarez/1


0
2017-08-01 18:11





基于@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');
    });
});

现在,你只需要在CSS中使用.focus-keyboard和.focus-mouse类进行切割。

.focus-keyboard{
    background:#eeeeee;
}
.focus-mouse{
    outline: 0;
}

0
2017-08-04 08:38