По умолчанию компонент 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 при выборе параметра?
Похоже, вы пытаетесь размыть параметр, но я думаю, вы хотите размыть сам выбор. Попробуйте selectElement.blur(); или evt.target.blur();
Обратите внимание, что ссылка перенаправляется в корневой элемент (div-оболочку), а не в select, поэтому это решение ничего не делает.
Ошибка, которую вы видите, выглядит связанной с TypeScript, но вы не включили ввод в свой вопрос/код.
Мне любопытно, почему вы хотите размыть Select. Это кажется ужасным с точки зрения доступности.
Я добавил это в событие onChange setTimeout(() => {document.activeElement.blur() }), и оно работает.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Обобщая некоторые комментарии в ответ:
Как предполагает @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, но мне нужно использовать это и для ненативных, у которых нет функции blur (у evt.target есть только атрибуты name и value). Как я мог сделать это для этого случая?
Я развил ваш пример песочницы, чтобы добавить неродной компонент выбора: codeandbox.io/s/practical-archimedes-3qcnt
@theJuls Трудность с неродным выбором связана со временем. onChange запускается при нажатии на MenuItem, и во время onChangeMenuItem все еще находится в фокусе. После закрытия меню/выбора div выбора получает фокус. Если вы вызываете document.activeElement.blur() внутри обратного вызова setTimeout, он работает так, как вы хотите: codeandbox.io/s/non-native-select-blur-jjiu8.
вдохновленные ответами @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
Вам нужно отложить эффект размытия. Сфокусированный элемент не находится на экране после выбора.