gpt4 book ai didi

reactjs - 滚动或选择项目时,多选框弹出框不断跳跃

转载 作者:行者123 更新时间:2023-12-03 13:34:35 24 4
gpt4 key购买 nike

滚动或选择项目时,多选框弹出窗口不断跳跃

Codepen https://codesandbox.io/s/material-demo-e5j8h

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import ListItemText from "@material-ui/core/ListItemText";
import Select from "@material-ui/core/Select";
import Checkbox from "@material-ui/core/Checkbox";

const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
}
};

const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];

export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);

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

return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}

最佳答案

跳转的原因与Menu的“内容 anchor ”功能有关。

来自https://material-ui.com/components/menus/#selected-menus (强调我的):

If used for item selection, when opened, simple menus attempt to vertically align the currently selected menu item with the anchor element, and the initial focus will be placed on the selected menu item. The currently selected menu item is set using the selected property (from ListItem). To use a selected menu item without impacting the initial focus or the vertical positioning of the menu, set the variant property to menu.

您还可以在variant prop的文档中找到类似的注释。 .

文档的其他相关部分是 getContentAnchorEl prop of Popover 的描述:

This function is called in order to retrieve the content anchor element. It's the opposite of the anchorEl prop. The content anchor element should be an element inside the popover. It's used to correctly scroll and set the position of the popover. The positioning strategy tries to make the content anchor element just above the anchor element.

Select 元素的默认行为是使用 Select 输入元素(关闭时显示所选项目的部分)作为“ anchor 元素” ”和最后选择的菜单项作为“内容 anchor 元素”。这意味着当 Popover 打开时,它会尝试将最后选定的菜单项(在 Popover 内)与 Select 输入元素 (在 Popover 后面)。

如果在 Select 上使用 multiple 属性,您有可能在 Popover 处于选中状态时更改最后选定的项目。打开(对于单选,它通常会在选择某些内容后立即关闭)。此外,由于并非所有菜单项都能同时容纳,因此最后选定的项目有时会滚动到 View 之外,这会强制 Popover 使用稍微不同的逻辑进行垂直对齐。

所有这一切的最终效果是沙盒中展示的奇怪的跳跃。您可以通过强制 Popover 使用 contentAnchorOffset of zero 来解决此问题通过指定 getContentAnchorEl: null 如下:

const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
getContentAnchorEl: null
};

您可能还想添加变体:“menu”以摆脱某些自动聚焦行为,这将导致它自动滚动到最后一个选定的项目。这对于单选来说是很好的行为,但在多选中不太有用,而且有点让人迷失方向。

设置 variant: "menu" 不足以消除跳转(没有 getContentAnchorEl: null)。这将导致它始终使用第一个菜单项作为内容 anchor ,这将导致较少的跳跃,但由于第一个菜单项有时在更改选择时会滚动到 View 之外,因此它仍然会进行一些跳跃。

下面是沙盒修改版本的完整代码,不再有任何奇怪的跳转(唯一的更改是 MenuProps):

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import ListItemText from "@material-ui/core/ListItemText";
import Select from "@material-ui/core/Select";
import Checkbox from "@material-ui/core/Checkbox";

const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
variant: "menu",
getContentAnchorEl: null
};

const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];

export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);

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

return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}

Edit Fix Jumping Select

关于reactjs - 滚动或选择项目时,多选框弹出框不断跳跃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59785482/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com