为什么 select() 在带有 ReactJS 的 Safari 上不起作用?

IT技术 reactjs safari
2021-05-24 15:23:05

每当我单击/点击/聚焦该字段时,我都希望获得一个 TextField 以选择当前在该字段中的整个文本。以下代码适用于 Chrome (71.0.3578.98),但不适用于 Safari (12.0.2)。任何想法为什么?

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  return (
    <>
      <h1>Test Focus React</h1>
      <input
        type="text"
        defaultValue="test"
        onFocus={event => {
          event.target.select();
        }}
      />
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑 pkqzz7nxz0

然而,这个没有任何 React 的静态 HTML 文件在 Safari 上运行良好。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Test Focus JS</title>
  </head>
  <body>
    <h1>Test Focus JS</h1>
    <input type="text" value="test" onClick="this.select();" />
  </body>
</html>

编辑 6l20oq76jn

谁能帮我看看如何让选择在带有 React 的 Safari 上工作?

3个回答

当与 DOM 交互之类的事情失败时,它通常与事件如何在不同上下文(react 与 onclick)中同步/异步触发有关,甚至与浏览器(Safari 有时会进行奇怪的优化)有关。

我猜它只会通过使其异步来工作,例如:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  return (
    <>
      <h1>Test Focus React</h1>
      <input
        type="text"
        defaultValue="test"
        onFocus={event => {
              // event properties must be copied to use async
              const target = event.target;
              setTimeout(() => target.select(), 0);
        }}
      />
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑测试焦点react

这是众所周知的问题,您基本上可以使用 set timeout

onFocus={event => {
  setTimeout(event.target.select.bind(event.target), 20);
}}

这是工作示例我在 safari 上进行了测试,没有任何问题。

我认为您想使用 Reactref来存储对实际inputDOM 元素的引用,以便您可以selectonClick方法中调用

查看文档,他们有一个很好的示例,您可以稍微修改一下以满足您的需求:https : //reactjs.org/docs/refs-and-the-dom.html

这应该有效,我认为:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);

    this.textInput = React.createRef();
    this.selectTextInput = this.selectTextInput.bind(this);
  }

  selectTextInput() {
    this.textInput.current.select();
  }

  render() {
    return (
      <div>
        <input 
          type="text" 
          defaultValue="pizza" 
          ref={this.textInput} 
          onClick={this.selectTextInput}
        />
      </div>
    );
  }
}

function App() {
  return (
    <CustomTextInput />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);