应用:以编程方式聚焦元素时焦点可见

mTv*_*mTv 7 javascript css reactjs

当我使用键盘聚焦或使用以编程方式聚焦时,我想将样式应用于我的元素HTMLElement.focus()。

例如在下面的例子中。我希望<div>最初或当我使用选项卡聚焦时具有蓝色边框。<div>我只希望当我使用鼠标单击时它具有红色边框。

这可能吗?

EDIT1:从使用按钮触发焦点更改为仅在渲染上触发焦点,因为这种情况对于我的实际问题并不准确。

EDIT2:从 vanilla JS 更改为 React,因为我认为这可能是问题所在。似乎它仍然像我想要的那样工作,但不在我的应用程序中:(。我不知道为什么。

const useFocusOnMount = (ref) => {
  React.useEffect(() => {
    if (ref.current) {
      ref.current.focus();
    }
  }, [ref]);
};


const App = (props) => {
  const divRef = React.useRef(null)
  
  useFocusOnMount(divRef);

  return (
  <div ref={divRef} role="listbox" tabindex="0" className="focusable">
    <div data-testid="displayValue">Lol</div>
  </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
.focusable {
  border: 1px solid lightgrey;
  outline: none;
}

.focusable:focus {
  border: 2px solid red;
}
.focusable:focus-visible {
  border: 2px solid blue;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

Kai*_*ido 7

不知道为什么你想要这个,我建议你找到另一种方法来做你想做的事(例如,为什么不使用 only :focus?)。
但是对于 hack,你可以欺骗浏览器认为你的 div 是可编辑的,它应该* 让它触发它的focus-visible规则。

const focusable = document.getElementById('focusable');
const button = document.getElementById('button');

const onClickHandler = (e) => {
  focusable.contentEditable = true;
  focusable.focus();
  focusable.contentEditable = false;
};

button.addEventListener("click", onClickHandler);
Run Code Online (Sandbox Code Playgroud)
.focusable {
  border: 1px solid lightgrey;
  outline: none;
}

.focusable:focus {
  border: 2px solid red;
}
.focusable:focus-visible {
  border: 2px solid blue;
}
Run Code Online (Sandbox Code Playgroud)
<div id="focusable" class="focusable" tabIndex=0>Lol</div>
<button id="button">Focus Lol</button>
Run Code Online (Sandbox Code Playgroud)

*我只在最新的 Chrome 和 Firefox 中进行了测试。