鼠标焦点上没有轮廓,但键盘焦点上仍然有轮廓
No outline on mouse focus but still have outline on keyboard focus?
当页面的元素有焦点(如链接或按钮)时,它们会显示轮廓。我希望这个轮廓只在键盘而不是鼠标聚焦时显示。
是否可以确定该元素是如何通过JavaScript获得焦点的?如果是,我该如何控制浏览器自己的大纲功能?
浏览器使用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
集,并将避免覆盖它。此处演示
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;
}
删除outline
对可访问性来说非常糟糕!理想情况下,只有当用户打算使用键盘时,焦环才会出现。
2018答案:使用:焦点可见。目前,W3C建议使用CSS来设计只关注键盘的样式。在主流浏览器支持它之前,您可以使用这个健壮的polyfill。它不需要添加额外的元素或更改tabindex
。
/* Remove outline for non-keyboard :focus */
*:focus:not(.focus-visible) {
outline: none;
}
/* Optional: Customize .focus-visible */
.focus-visible {
outline-color: lightgreen;
}
我还写了一篇更详细的帖子和一些演示,以防你需要更多信息。
我可以看到的一个简单方法是使用鼠标事件来防止焦点启动。
$('#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/
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
基于@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键盘和.focus鼠标类进行剪切即可。
.focus-keyboard{
background:#eeeeee;
}
.focus-mouse{
outline: 0;
}
如果用户当前使用鼠标或键盘,您可以将类添加到正文中以了解css
document.body.addEventListener('mousedown', function() {
document.body.classList.add('using-mouse');
});
document.body.addEventListener('keydown', function() {
document.body.classList.remove('using-mouse');
});
和在css
:focus {
outline: #08f auto 2px;
}
body.using-mouse :focus {
outline: none;
}
- keyup事件处理程序更改焦点不适用于快速键入
- 单击时将焦点更改为元素
- 后焦点更改为IE 11中的地址栏,而不是转移到表单中的下一个控件
- 在IE9中的输入字段中输入焦点最近按钮
- Javascript游戏输入失去焦点
- ExtJS网格单元格编辑器,防止焦点松动问题
- 检查元素是如何获得焦点的
- angularjs移除焦点上的活动类并添加到下一个项目
- Don'不允许将焦点集中在自动完成的选择上
- 当点击另一件事时,将焦点设置为一件事
- 文本框焦点上的自动完成菜单
- 如何检测哪个窗口是焦点
- 可以't从Youtube IFrame更改焦点
- 在jAlert之后设置焦点
- 在文本区域的焦点上分割渐变
- 使用Redux和React添加焦点更改类
- iFrames并再次检测焦点
- 如何获得React Native TextInput以在提交后保持焦点
- 以编程方式设置在锚点上时,焦点轮廓不显示
- 鼠标焦点上没有轮廓,但键盘焦点上仍然有轮廓