You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI多选下拉框点击时body自动添加Padding问题求解决方案

MUI多选下拉框点击时body自动添加padding的解决方案

问题描述

实现MUI多选下拉框时,点击下拉框展开选项,body元素会被自动添加padding。已尝试在MenuProps中配置disableScrollLock={true}并传入Select组件,但问题仍未解决。

实现代码

import * as React from 'react';
import MenuItem from '@mui/material/MenuItem';
import ListItemText from '@mui/material/ListItemText';
import Select from '@mui/material/Select';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import Checkbox from '@mui/material/Checkbox';
import SearchIcon from "@mui/icons-material/Search";
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import ListItemIcon from "@material-ui/core/ListItemIcon";
import { makeStyles } from "@material-ui/core/styles";

const ITEM_HEIGHT = 50;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  PaperProps: {
    sx: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width:220,
      fontSize:'2rem'
    } 
  },
};

const classes = makeStyles((theme) => ({
  formControl: {
    margin: theme.spacing(1),
    width: 300
  },
  indeterminateColor: {
    color: "#f50057"
  },
  selectAllText: {
    fontWeight: 500
  },
  selectedAll: {
    backgroundColor: "rgba(0, 0, 0, 0.08)",
    "&:hover": {
      backgroundColor: "rgba(0, 0, 0, 0.08)"
    }
  }
}));

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 MultipleSelectCheckmarks({id,sendDataToParentCity,sendDataToParentBrand,sendDataToParentSKUs}) {

  const [searchText, setSearchText]    = React.useState("");
  const [personName, setPersonName]    = React.useState([]);
  const [optionLength,setOptionLength] = React.useState();
  const isAllSelected = names.length > 0 && personName.length === names.length;

  const displayedOptions = names.filter((option) =>option.toLowerCase().indexOf(searchText.toLowerCase()) > -1)

  const handleChange = (event) => {
   
    const value = event.target.value;
    if (value[value.length - 1] === "all") {
      setPersonName(personName.length === names.length ? [] : names);
      return;
    }
    if(!value.includes(undefined))
        setPersonName(value); 

    setOptionLength(value.join(',').split(',').length-1)    
        
    if(id==1)
        sendDataToParentCity(value)
    else if(id==2)       
        sendDataToParentBrand(value) 
    else if(id==3)
        sendDataToParentSKUs(value)

    };

  const serachSet = (event)=>{
    setSearchText(event.target.value)
  }

  return (
    <div>
        <Select
        
        defaultValue = {'Select Brand'}
        autoWidth={true}
        style={{width: "13.4rem",height: "2.3rem",background: "white"}}
          id="search-select"
          sx={{
            '& #search-select': {
                fontSize: '13px',
             }
           }}
          multiple
          value={personName}
          onChange={handleChange}
          renderValue={(selected) =>selected.join(',').split(',').length===names.length ? "All Selected" : selected.join(',').split(',').length==1 ? selected.join(',').split(',')[0] :(selected.join(',').split(',')[0]+" & "+optionLength)  +" Others!"}
          MenuProps={MenuProps}
          onClose={() => setSearchText("")}
          IconComponent = {KeyboardArrowDownIcon}
          withAll={true}
        >
            <MenuItem  onKeyDown={e => e.stopPropagation()}>
            <TextField 
              size="small"
              placeholder="Search"
              sx={{fontSize: '2rem'}}
              fullWidth
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start" >
                    <SearchIcon />
                  </InputAdornment>
                )
              }}
              onChange={serachSet}
            />
          </MenuItem>
          
        <MenuItem value="all">
          <ListItemIcon>
            <Checkbox
              checked={isAllSelected}
              indeterminate={
                personName.length > 0 && personName.length < names.length
              }
            />
          </ListItemIcon>
          <ListItemText
            classes={{ primary: classes.selectAllText }}
            primary="Select All"
          />
        </MenuItem>
        

          {displayedOptions.map((name) => (
            <MenuItem key={name} value={name}>
              <Checkbox checked={personName.indexOf(name) > -1} />
              <ListItemText primary={name} />
            </MenuItem>
          ))}
        </Select>
    </div>
  );
}

解决方案

1. 修正MenuProps的配置位置

问题核心是disableScrollLock的配置位置错误——你之前的代码中完全遗漏了这个属性,或者错误地嵌套在了PaperProps内部。正确的做法是将该属性直接定义在MenuProps顶层:

const MenuProps = {
  disableScrollLock: true, // 直接放在MenuProps顶层
  PaperProps: {
    sx: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width:220,
      fontSize:'2rem'
    } 
  },
};

MUI的Select组件展开菜单时,默认会启用滚动锁定(scroll lock),该功能会给body添加padding以抵消滚动条隐藏后的空隙。将disableScrollLock设为true可以完全禁用这个行为,阻止body被添加额外padding。

2. 全局CSS强制覆盖(备选方案)

如果上述方法无效,可能是MUI默认样式优先级较高,可以通过全局CSS强制移除body的padding:

body.Mui-disabled-scroll-lock {
  padding-right: 0 !important;
}

3. 排查冲突组件

检查项目中是否有其他组件(如Modal、Drawer等)也启用了scroll lock功能,多个组件的滚动锁定逻辑可能产生冲突,导致body的padding无法被正确移除。

内容的提问来源于stack exchange,提问作者Muhammad Usama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:05:24