Компонент Blur Material UI Select в событии onChange

По умолчанию компонент Select в MaterialUI остается в фокусе после выбора параметра. Это поведение можно увидеть во всех их примерах в их документах

Я хотел бы, чтобы элемент размывался после того, как что-то выбрано. Вот как сейчас выглядит мой код:

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 при выборе параметра?

Вам нужно отложить эффект размытия. Сфокусированный элемент не находится на экране после выбора.

Akxe 29.12.2020 22:22

Похоже, вы пытаетесь размыть параметр, но я думаю, вы хотите размыть сам выбор. Попробуйте selectElement.blur(); или evt.target.blur();

2pha 29.12.2020 23:25

Обратите внимание, что ссылка перенаправляется в корневой элемент (div-оболочку), а не в select, поэтому это решение ничего не делает.

ericgio 30.12.2020 00:20

Ошибка, которую вы видите, выглядит связанной с TypeScript, но вы не включили ввод в свой вопрос/код.

ericgio 30.12.2020 00:42

Мне любопытно, почему вы хотите размыть Select. Это кажется ужасным с точки зрения доступности.

Ryan Cogswell 31.12.2020 18:13

Я добавил это в событие onChange setTimeout(() => {document.activeElement.blur() }), и оно работает.

Vivek Kapoor 19.10.2022 13:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
6
4 933
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Обобщая некоторые комментарии в ответ:

Как предполагает @2pha, использование evt.target.blur(), вероятно, будет правильным решением:

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

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

        console.info(document.activeElement); // <select>
        evt.target.blur();
        console.info(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

Ссылка не работает, потому что она пересылается корневому элементу (a div), а не элементу select.

Ошибка, которую вы видите, связанная с document.activeElement, похоже, связана с TypeScript. Вы видите это, потому что document.activeElement обычно имеет тип Element, у которого нет метода blur. Вам нужно будет указать тип HTMLSelectElement, но, похоже, не стоит идти по этому пути, поскольку проще просто использовать evt.target.

Спасибо! Это сработало для нативных компонентов Select, но мне нужно использовать это и для ненативных, у которых нет функции blurevt.target есть только атрибуты name и value). Как я мог сделать это для этого случая?

theJuls 30.12.2020 17:07

Я развил ваш пример песочницы, чтобы добавить неродной компонент выбора: codeandbox.io/s/practical-archimedes-3qcnt

theJuls 30.12.2020 17:13

@theJuls Трудность с неродным выбором связана со временем. onChange запускается при нажатии на MenuItem, и во время onChangeMenuItem все еще находится в фокусе. После закрытия меню/выбора div выбора получает фокус. Если вы вызываете document.activeElement.blur() внутри обратного вызова setTimeout, он работает так, как вы хотите: codeandbox.io/s/non-native-select-blur-jjiu8.

Ryan Cogswell 30.12.2020 20:40

вдохновленные ответами @ericgio и @Ryan Cogswell, есть еще один способ решить эту проблему. Для неродных элементов мы можем назначить функцию setTimeout для onClose, которая будет размывать элемент после выбора опции в меню.

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

  const handleChangeEvent = (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 = {handleChangeEvent}>
          <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

Другие вопросы по теме