【问题标题】:Blur Material UI Select component on the onChange event在 onChange 事件上模糊材质 UI 选择组件
【发布时间】:2020-12-22 16:03:22
【问题描述】:

默认情况下,MaterialUI 的 Select 组件在选择一个选项后会保持焦点。这种行为可以在他们docs的所有示例中看到

我希望元素在选择某些内容后模糊。这是我的代码目前的样子:

const App = () => {
    const [selectedValue, setSelectedValue] = useState('')

    const selectElement = useRef(null);

  return (
        <Select
            native
            ref={selectElement}
            value={selectedValue}
            onChange={(evt) => {
                setSelectedValue(evt.target.value)

                // Attempt at blurring the element upon selection using the useRef:
                selectElement.current.blur(); // Nothing happens

                // Attempt at blurring the element upon selection using activeElement:
                document.activeElement.blur(); // Get Error: "Property 'blur' does not exist on type 'Element'."
            }}
        >
            <option value='option 1'>Option 1</option>
            <option value='option 2'>Option 2</option>
            <option value='option 3'>Option 3</option>
        </Select>
  );
};

正如您在代码中看到的那样,我尝试使用我发现的两种不同方法来做到这一点:

  • 通过useRef():这没有任何作用,没有错误或任何东西,但不会模糊我的元素

  • 通过document.activeElement:这给了我一个错误,显然属性blur 在类型元素上不存在。

在选择选项时模糊我的 Select 组件的正确方法是什么?

【问题讨论】:

  • 您需要延迟模糊效果。选择后焦点元素不在屏幕上。
  • 看起来您正在尝试模糊选项,但我认为您想模糊选择本身。试试selectElement.blur();evt.target.blur();
  • 请注意,ref 被转发到根元素(包装 div),而不是 select,这就是该解决方案什么都不做的原因。
  • 您看到的错误看起来与 TypeScript 相关,但您没有在问题/代码中输入任何内容。
  • 我很好奇你为什么要模糊选择。从可访问性的角度来看,这似乎是一件可怕的事情。

标签: javascript reactjs material-ui dom-events


【解决方案1】:

将部分cmets总结为答案:

正如@2pha 建议的那样,使用evt.target.blur() 可能是要走的路:

const App = () => {
  const [selectedValue, setSelectedValue] = useState('');

  return (
    <Select
      native
      value={selectedValue}
      onChange={(evt) => {
        setSelectedValue(evt.target.value);

        console.log(document.activeElement); // <select>
        evt.target.blur();
        console.log(document.activeElement); // <body>
      }}>
      <option value="option 1">Option 1</option>
      <option value="option 2">Option 2</option>
      <option value="option 3">Option 3</option>
    </Select>
  );
};

沙盒:https://codesandbox.io/s/empty-night-oqlgr

引用不起作用,因为 it's being forwarded to the root elementdiv)不是 select 元素。

您看到的与 document.activeElement 相关的错误看起来与 TypeScript 相关。您看到它是因为document.activeElement 通常类型为Element,它没有blur 方法。您需要指定 HTMLSelectElement 类型,但似乎不值得追求这条路线,因为只使用 evt.target 更直接。

【讨论】:

  • 谢谢!这适用于本机 Select 组件,但我确实需要将其用于非本机组件,对于没有 blur 函数的任何组件(evt.target 只有 namevalue 属性)。这种情况我该怎么办?
  • 我已经分叉了您的沙箱示例以添加非本机选择组件:codesandbox.io/s/practical-archimedes-3qcnt
  • @theJuls 非本地选择的困难在于时机。 onChange 通过单击MenuItem 触发,在onChangeMenuItem 仍然具有焦点。 Menu/Select 关闭后,Select 的div 获得焦点。如果您在setTimeout 回调中调用document.activeElement.blur(),它会按需要工作:codesandbox.io/s/non-native-select-blur-jjiu8
【解决方案2】:

受@ericgio 和@Ryan Cogswell 的启发,有另一种方法可以解决这个问题。对于非原生元素,我们可以为onClose 分配一个setTimeout 函数,它会在从菜单中选择选项后模糊元素。

const App = () => {
  const [selectedValue, setSelectedValue] = useState('');
  const [age, setAge] = React.useState('');

  const handleChange = (event) => {
    setAge(event.target.value);
  };

  return (
    <div>
      <div>
        <Select
          style={{ width: '200px' }}
          native
          value={selectedValue}
          onChange={(evt) => {
            setSelectedValue(evt.target.value);
            evt.target.blur();
          }}>
          <option value="option 1">Option 1</option>
          <option value="option 2">Option 2</option>
          <option value="option 3">Option 3</option>
        </Select>
      </div>
      <FormControl style={{ width: '200px' }}>
        <InputLabel id="demo-simple-select-label">Age</InputLabel>
        <Select
          onClose={() => {
            setTimeout(() => {
              document.activeElement.blur();
            }, 0);
          }}
          value={age}
          onChange={handleChange}>
          <MenuItem value={10}>Ten</MenuItem>
          <MenuItem value={20}>Twenty</MenuItem>
          <MenuItem value={30}>Thirty</MenuItem>
        </Select>
      </FormControl>
    </div>
  );
};

沙盒:- https://codesandbox.io/s/wonderful-microservice-xufqc

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    相关资源
    最近更新 更多