我正在开发一个 React 组件,其中有一个自定义
select
下拉列表,我想在单击按钮时以编程方式打开它。我使用 useRef
来引用 select
元素,并且我尝试在单击按钮时触发其 click
事件,但它无法按预期工作。下面是我的代码以及我到目前为止所尝试过的。
const CustomDatePicker = ({ birthdate, handle }) => {
const selectRef = useRef(null);
const [month, setMonth] = useState('0');
const [day, setDay] = useState('0');
const [year, setYear] = useState('0');
const months = [
{ value: '01', label: 'January' },
{ value: '02', label: 'February' },
{ value: '03', label: 'March' },
{ value: '04', label: 'April' },
{ value: '05', label: 'May' },
{ value: '06', label: 'June' },
{ value: '07', label: 'July' },
{ value: '08', label: 'August' },
{ value: '09', label: 'September' },
{ value: '10', label: 'Octorber' },
{ value: '11', label: 'November' },
{ value: '12', label: 'December' },
];
const days = Array.from({ length: 31 }, (_, i) => i + 1).map((day) => ({
value: day < 10 ? `0${day}` : `${day}`,
label: day.toString(),
}));
const years = Array.from({ length: 125 }, (_, i) => 2024 - i).map((year) => ({
value: year.toString(),
label: year.toString(),
}));
const handleMonthChange = (event: any) => {
setMonth(event.target.value);
handle({ ...birthdate, month: parseInt(event.target.value) });
};
const handleDayChange = (event: any) => {
setDay(event.target.value);
handle({ ...birthdate, day: parseInt(event.target.value) });
};
const handleYearChange = (event: any) => {
setYear(event.target.value);
handle({ ...birthdate, year: parseInt(event.target.value) });
};
const handleIconClick = () => {
// Trigger click event on select element
selectRef.current.click();
};
return (
<div style={{ display: 'flex', gap: '8px' }}>
<div style={{ flex: 1, position: 'relative' }}>
<select ref={selectRef} value={month} onChange={handleMonthChange} className={month == '0' ? styles.date_selector_placeholder : styles.date_selector}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Month</option>
{months.map((month) => (
<option key={month.value} value={month.value} className={styles.date_selector_option_item}>
{month.label}
</option>
))}
</select>
<CustomIcon onClick={handleIconClick} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
<div style={{ flex: 0.5, position: 'relative' }}>
<select value={day} onChange={handleDayChange} className={day == '0' ? styles.date_selector_placeholder : styles.date_selector} style={{ flex: 0.5 }}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Day</option>
{days.map((day) => (
<option key={day.value} value={day.value} className={styles.date_selector_option_item}>
{day.label}
</option>
))}
</select>
<CustomIcon onClick={handleIconClick} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
<div style={{ flex: 0.5, position: 'relative' }}>
<select value={year} onChange={handleYearChange} className={year == '0' ? styles.date_selector_placeholder : styles.date_selector} style={{ flex: 0.5 }}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Year</option>
{years.map((year) => (
<option key={year.value} value={year.value} className={styles.date_selector_option_item}>
{year.label}
</option>
))}
</select>
<CustomIcon onClick={handleIconClick} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
</div>
);
};
我预计当我单击按钮时会打开
select
下拉菜单,但什么也没发生。我添加了一个 click
事件来触发下拉菜单的打开,但它无法正常运行。我还检查了是否使用 select
正确选择了 ref
元素,确实如此。
尝试为每个选择元素分配一个引用(selectRefs.month、selectRefs.day、selectRefs.year)。单击自定义图标时,它会使用其引用触发相应的选择元素的单击。 检查下面的代码:
const CustomDatePicker = ({ birthdate, handle }) => {
const selectRefs = {
month: useRef(null),
day: useRef(null),
year: useRef(null)
};
const [month, setMonth] = useState('0');
const [day, setDay] = useState('0');
const [year, setYear] = useState('0');
const months = [
{ value: '01', label: 'January' },
{ value: '02', label: 'February' },
{ value: '03', label: 'March' },
{ value: '04', label: 'April' },
{ value: '05', label: 'May' },
{ value: '06', label: 'June' },
{ value: '07', label: 'July' },
{ value: '08', label: 'August' },
{ value: '09', label: 'September' },
{ value: '10', label: 'Octorber' },
{ value: '11', label: 'November' },
{ value: '12', label: 'December' },
];
const days = Array.from({ length: 31 }, (_, i) => i + 1).map((day) => ({
value: day < 10 ? `0${day}` : `${day}`,
label: day.toString(),
}));
const years = Array.from({ length: 125 }, (_, i) => 2024 - i).map((year) => ({
value: year.toString(),
label: year.toString(),
}));
const handleMonthChange = (event: any) => {
setMonth(event.target.value);
handle({ ...birthdate, month: parseInt(event.target.value) });
};
const handleDayChange = (event: any) => {
setDay(event.target.value);
handle({ ...birthdate, day: parseInt(event.target.value) });
};
const handleYearChange = (event: any) => {
setYear(event.target.value);
handle({ ...birthdate, year: parseInt(event.target.value) });
};
const handleIconClick = (ref) => {
ref.current.click();
};
return (
<div style={{ display: 'flex', gap: '8px' }}>
<div style={{ flex: 1, position: 'relative' }}>
<select ref={selectRefs.month} value={month} onChange={handleMonthChange} className={month == '0' ? styles.date_selector_placeholder : styles.date_selector}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Month</option>
{months.map((month) => (
<option key={month.value} value={month.value} className={styles.date_selector_option_item}>
{month.label}
</option>
))}
</select>
<CustomIcon onClick={() => handleIconClick(selectRefs.month)} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
<div style={{ flex: 0.5, position: 'relative' }}>
<select ref={selectRefs.day} value={day} onChange={handleDayChange} className={day == '0' ? styles.date_selector_placeholder : styles.date_selector} style={{ flex: 0.5 }}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Day</option>
{days.map((day) => (
<option key={day.value} value={day.value} className={styles.date_selector_option_item}>
{day.label}
</option>
))}
</select>
<CustomIcon onClick={() => handleIconClick(selectRefs.day)} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
<div style={{ flex: 0.5, position: 'relative' }}>
<select ref={selectRefs.year} value={year} onChange={handleYearChange} className={year == '0' ? styles.date_selector_placeholder : styles.date_selector} style={{ flex: 0.5 }}>
<option value="0" disabled className={styles.date_selector_option_item_placeholder}>Year</option>
{years.map((year) => (
<option key={year.value} value={year.value} className={styles.date_selector_option_item}>
{year.label}
</option>
))}
</select>
<CustomIcon onClick={() => handleIconClick(selectRefs.year)} name='arrowDownGrey' width={23} height={17} style={{ position: 'absolute', top: '14px', right: '12px' }} />
</div>
</div>
);
};
请参考此存储库。 https://github.com/santiagoourregobotero/customized-select
要实现选择元素的自定义外观,常用技术包括将选择的不透明度设置为 0,有效隐藏它,然后使用替代元素自定义其外观。这种方法可以为选择的元素提供更专业和定制的外观和感觉。
通过将选择元素的不透明度设置为 0,它在视觉上变得隐藏,同时仍然保留其功能。随后,可以将自定义样式应用于其他元素,例如 div 或 span,以创建所选元素的视觉吸引力和个性化表示。这种方法在设计方面提供了更大的灵活性,并允许与网页或应用程序的整体外观和感觉更加无缝集成。