最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to pragrammatically focus on HTML element without outline? - Stack Overflow

programmeradmin5浏览0评论

Caution: :focus { outline: none } should not be the answer as it also prevents outline when navigating by tab key

Clicking a button does not show outline but the button bees document.activeElement (JSFiddle). I want to mimic this behavior without mouse clicking.

The method should:

  1. make the element as document.activeElement.
  2. not cause outline
  3. still allow outline when pressing keyboard tab key

(If anyone asks, my current intention is to focus a modal dialog and return the focus to the previous focused element when the dialog is closed. This requires preventing outline for seamless experience.)

pseudo code:

showDialog();

function whenDialogClosed() {
  previouslyFocused.focus(); // should not display outline
}

Caution: :focus { outline: none } should not be the answer as it also prevents outline when navigating by tab key

Clicking a button does not show outline but the button bees document.activeElement (JSFiddle). I want to mimic this behavior without mouse clicking.

The method should:

  1. make the element as document.activeElement.
  2. not cause outline
  3. still allow outline when pressing keyboard tab key

(If anyone asks, my current intention is to focus a modal dialog and return the focus to the previous focused element when the dialog is closed. This requires preventing outline for seamless experience.)

pseudo code:

showDialog();

function whenDialogClosed() {
  previouslyFocused.focus(); // should not display outline
}
Share Improve this question edited Sep 17, 2018 at 3:44 Kagami Sascha Rosylight asked Aug 17, 2016 at 2:34 Kagami Sascha RosylightKagami Sascha Rosylight 1,4922 gold badges16 silver badges31 bronze badges 9
  • 1 showDialog mimics modal dialog inside of a page with normal divs. – Kagami Sascha Rosylight Commented Aug 17, 2016 at 2:50
  • 1 This question is a little bit confusing, after a short conversation he need to simulate the focus of elements, one for the main-window and one for the simulated popup! – Grim Commented Aug 17, 2016 at 3:08
  • I modified the question and I hope it is now more understandable. – Kagami Sascha Rosylight Commented Aug 17, 2016 at 3:23
  • You either show outline when an element is focused or you don't. There's no two kinds of focus. If it satisfies you, you could disable outline, and reenable it on blur or keydown, so that if someone does tab, it'd be shown. – Amadan Commented Aug 17, 2016 at 4:13
  • 1 Be careful though, not all UAs do fire a focus event on button's click – Kaiido Commented Aug 17, 2016 at 5:15
 |  Show 4 more ments

2 Answers 2

Reset to default 3

CSS finally got an answer by adding a pseudo-class :focus-visible that activates exactly when browser decides to do.

For this reason, modern browsers apply simple heuristics to determine whether or not to apply their default focus styling. In general, if an element received focus as a result of a mouse/pointer click, browsers will suppress their default focus indication.

As of 2021, all modern browsers support this, however if you need to support older browsers, use a polyfill and do this:

/*
 * .js-focus-visible is automatically added to document.body
 * to ensure the rules run only in JS-supported environment
 */

.js-focus-visible .your-selector:focus:not(.focus-visible) { outline: none }

Demo:

focusrandom.addEventListener("click", () => {
  const num = Math.ceil(Math.random() * 5);
  const button = document.getElementById(`button${num}`);
  button.focus();
});
wofocusrandom.addEventListener("click", () => {
  const num = Math.ceil(Math.random() * 5);
  const button = document.getElementById(`wobutton${num}`);
  button.focus();
});
.js-focus-visible .apply button:focus:not(.focus-visible) {
  outline: none;
}
<script src="https://unpkg./focus-visible"></script>
<p class="apply">
  With focus-visible:
  <button id="button1">1</button>
  <button id="button2">2</button>
  <button id="button3">3</button>
  <button id="button4">4</button>
  <button id="button5">5</button>
</p>
<p>
  Without focus-visible:
  <button id="wobutton1">1</button>
  <button id="wobutton2">2</button>
  <button id="wobutton3">3</button>
  <button id="wobutton4">4</button>
  <button id="wobutton5">5</button>
</p>

<button id="focusrandom">Focus random button</button>
<button id="wofocusrandom">Focus random button without focus-visible</button>

(From https://stackoverflow./a/50571098/2460034. Thank you Aaron!)

You could add a transition to the unfocus.

var dial = document.getElementById('dial');
var focused;
function openDialog(){
  document.body.className="havingFocus";
  dial.className="";
  focused = document.activeElement;
  document.getElementById('new_focus').focus();
}
function closeDialog(){
  document.body.className="";
  dial.className="hidden";  
  focused.focus();
}
.havingFocus * {
  transition: all 0s;
  transition-delay: 20000s;
  outline: 1px solid transparent;
}
*:focus{
  transition-delay:0s;
  outline: 2px solid highlight;
}

div{
  margin:20px;
  border:1px solid black;
  padding: 20px;
  position:relative;
}
div:before{
  content:'x';
  position: absolute;
  right:10px;
  top:0px;
}

.hidden{
  display:none;
}
<input value="test123"/>
<div id="dial" class="hidden">
  <input value="in dialog" id="input"/>
  <button onclick="closeDialog()" id="new_focus">close</button>
</div>
<button onclick="openDialog()">open</button>

发布评论

评论列表(0)

  1. 暂无评论