По умолчанию компонент 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() }), и оно работает.
Обобщая некоторые комментарии в ответ:
Как предполагает @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
, и во время onChange
MenuItem
все еще находится в фокусе. После закрытия меню/выбора 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
Вам нужно отложить эффект размытия. Сфокусированный элемент не находится на экране после выбора.