如何在 flexbox 布局上获得溢出滚动条
How to get overflow scrollbar on flexbox layout
我正在使用 React MUI 构建网络聊天。对于布局,我想使用 Flexbox,因为聊天输入设置为自动增长,我希望消息提要容器能够自动调整高度。
但是,我很难让溢出滚动条与 flex 布局一起使用。
- 当我将消息长度设置为 20 时,消息提要溢出到容器上方,即使我有
overflowY: "auto"
也无法获得滚动条
- 当我将联系人长度设置为 20 时,它会将内容下推,即使我将根容器设置为
height: '100vh'
我已经阅读了“How can I combine flexbox and vertical scroll in a full-height app?', and 'Scrolling a flexbox with overflowing content', and 'How to make a scrollable container with dynamic height using Flexbox”的答案。使用技巧,例如在父级 div 上设置 overflow: 'hidden'
,或将 minHeight: 0
设置到列表和提要容器。我仍然无法让它工作。我正在努力获得正确的滚动行为并且不知道我在哪里失踪。请帮忙!
这是代码沙盒:https://codesandbox.io/s/mui-webchat-lsn3tm?file=/demo.js
// ----------------------------------------------------------
const contactLenghth = 10;
const messageLength = 20;
// ----------------------------------------------------------
export default function Chat() {
return (
<main
style={{
height: "100vh",
display: "flex",
flexDirection: "column"
}}
>
<AppBar position="sticky">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
LOGO
</Typography>
<Button color="inherit">Login</Button>
</Toolbar>
</AppBar>
<Grid container direction="row" alignItems="stretch" sx={{ flexGrow: 1 }}>
<Grid
item
md={3}
sx={{
display: { xs: "none", sm: "flex" },
flexDirection: "column",
overflowY: "auto",
borderRight: "1px solid lightgrey"
}}
>
<Toolbar>
<Typography variant="h6"> Contacts </Typography>
</Toolbar>
<Divider />
<List>
{[...Array(contactLenghth)].map((n, i) => (
<ListItemButton key={i}>
<ListItem disablePadding>
<ListItemAvatar>
<Avatar />
</ListItemAvatar>
<ListItemText primary={`Contact ${i + 1}`} />
</ListItem>
</ListItemButton>
))}
</List>
</Grid>
<Grid
item
xs={12}
md={9}
sx={{ display: "flex", flexDirection: "column" }}
>
<Toolbar>
<Avatar sx={{ mr: 2 }} />
<ListItemText primary="John Doe" />
</Toolbar>
<Divider />
<Stack
direction="column"
spacing={1}
p={2}
justifyContent="flex-end"
sx={{ flexGrow: 1, overflowY: "auto", height: 0 }}
>
{[...Array(messageLength)].map((n, i) => (
<Stack
key={i}
direction="row-reverse"
spacing={2}
justifyContent="end"
>
<Box
sx={{
px: 2,
py: 1,
maxWidth: "60%",
borderRadius: 20,
bgcolor: "secondary.main",
color: "#fff"
}}
>
<Typography>Test message {i + 1}</Typography>
</Box>
</Stack>
))}
</Stack>
<Stack direction="row" p={2} alignItems="flex-end">
<TextField
placeholder="Message"
fullWidth
multiline
maxRows={5}
sx={{
flexGrow: 1,
borderRadius: 7,
"& fieldset": { borderRadius: 7 }
}}
/>
<Box p={1}>
<IconButton>
<SendIcon />
</IconButton>
</Box>
</Stack>
</Grid>
</Grid>
</main>
);
}
问题出在 属性 justifyContent="flex-end"
你的堆栈上。
<Stack
direction="column"
spacing={1}
p={2}
justifyContent="flex-end"
sx={{ flexGrow: 1, overflowY: "auto", height: 0 }}
>
解决方案
您可以将 属性 替换为 direction="column-reverse"
。因为,这是一个聊天应用程序。您可以使用 unshift 将消息附加到开始。
备用解决方案:
你可以保持方向为direction="column"
。有一个 JS 函数,它会定期检查 div 并将内容滚动到底部
function scrollToBottom(){
var element = document.getElementById("yourDiv");
element.scrollTop = element.scrollHeight;
}
//checking every 1sec
window.setInterval(scrollToBottom, 1000)
我正在使用 React MUI 构建网络聊天。对于布局,我想使用 Flexbox,因为聊天输入设置为自动增长,我希望消息提要容器能够自动调整高度。
但是,我很难让溢出滚动条与 flex 布局一起使用。
- 当我将消息长度设置为 20 时,消息提要溢出到容器上方,即使我有
overflowY: "auto"
也无法获得滚动条
- 当我将联系人长度设置为 20 时,它会将内容下推,即使我将根容器设置为
height: '100vh'
我已经阅读了“How can I combine flexbox and vertical scroll in a full-height app?', and 'Scrolling a flexbox with overflowing content', and 'How to make a scrollable container with dynamic height using Flexbox”的答案。使用技巧,例如在父级 div 上设置 overflow: 'hidden'
,或将 minHeight: 0
设置到列表和提要容器。我仍然无法让它工作。我正在努力获得正确的滚动行为并且不知道我在哪里失踪。请帮忙!
这是代码沙盒:https://codesandbox.io/s/mui-webchat-lsn3tm?file=/demo.js
// ----------------------------------------------------------
const contactLenghth = 10;
const messageLength = 20;
// ----------------------------------------------------------
export default function Chat() {
return (
<main
style={{
height: "100vh",
display: "flex",
flexDirection: "column"
}}
>
<AppBar position="sticky">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
LOGO
</Typography>
<Button color="inherit">Login</Button>
</Toolbar>
</AppBar>
<Grid container direction="row" alignItems="stretch" sx={{ flexGrow: 1 }}>
<Grid
item
md={3}
sx={{
display: { xs: "none", sm: "flex" },
flexDirection: "column",
overflowY: "auto",
borderRight: "1px solid lightgrey"
}}
>
<Toolbar>
<Typography variant="h6"> Contacts </Typography>
</Toolbar>
<Divider />
<List>
{[...Array(contactLenghth)].map((n, i) => (
<ListItemButton key={i}>
<ListItem disablePadding>
<ListItemAvatar>
<Avatar />
</ListItemAvatar>
<ListItemText primary={`Contact ${i + 1}`} />
</ListItem>
</ListItemButton>
))}
</List>
</Grid>
<Grid
item
xs={12}
md={9}
sx={{ display: "flex", flexDirection: "column" }}
>
<Toolbar>
<Avatar sx={{ mr: 2 }} />
<ListItemText primary="John Doe" />
</Toolbar>
<Divider />
<Stack
direction="column"
spacing={1}
p={2}
justifyContent="flex-end"
sx={{ flexGrow: 1, overflowY: "auto", height: 0 }}
>
{[...Array(messageLength)].map((n, i) => (
<Stack
key={i}
direction="row-reverse"
spacing={2}
justifyContent="end"
>
<Box
sx={{
px: 2,
py: 1,
maxWidth: "60%",
borderRadius: 20,
bgcolor: "secondary.main",
color: "#fff"
}}
>
<Typography>Test message {i + 1}</Typography>
</Box>
</Stack>
))}
</Stack>
<Stack direction="row" p={2} alignItems="flex-end">
<TextField
placeholder="Message"
fullWidth
multiline
maxRows={5}
sx={{
flexGrow: 1,
borderRadius: 7,
"& fieldset": { borderRadius: 7 }
}}
/>
<Box p={1}>
<IconButton>
<SendIcon />
</IconButton>
</Box>
</Stack>
</Grid>
</Grid>
</main>
);
}
问题出在 属性 justifyContent="flex-end"
你的堆栈上。
<Stack
direction="column"
spacing={1}
p={2}
justifyContent="flex-end"
sx={{ flexGrow: 1, overflowY: "auto", height: 0 }}
>
解决方案
您可以将 属性 替换为 direction="column-reverse"
。因为,这是一个聊天应用程序。您可以使用 unshift 将消息附加到开始。
备用解决方案:
你可以保持方向为direction="column"
。有一个 JS 函数,它会定期检查 div 并将内容滚动到底部
function scrollToBottom(){
var element = document.getElementById("yourDiv");
element.scrollTop = element.scrollHeight;
}
//checking every 1sec
window.setInterval(scrollToBottom, 1000)