效果

DOM布局

const label = {  lettersort: false,  paramname: "label",  paramid: 0,  title: "车源列表筛选项",  option: [{      value: 1,      text: "全部"    },    {      value: 2,      text: "本地求购"    },    {      value: 3,      text: "精准收车"    },    {      value: 4,      text: "全国收车"    },    {      value: 5,      text: "同行询价"    },    {      value: 6,      text: "可批可售"    },    {      value: 7,      text: "车抵贷款"    },    {      value: 8,      text: "消费贷款"    },    {      value: 9,      text: "商家库容"    },    {      value: 10,      text: "代理合作"    },    {      value: 11,      text: "过户转籍"    },    {      value: 12,      text: "寻车拖车"    },    {      value: 13,      text: "解压抵押"    },    {      value: 14,      text: "抵押核验"    }  ]}filterDom = () => {    let filterJson = label;    let arr = filterJson.option;    return (        <div ref="filterBar" className="filter-list">            {arr.map((item, index) => {                if (item.value == this.state.filterSelect) {                    return (                        <div                            ref={item.value}                            className="filter-item active"                            key={index}                            value={item.value}>                            {item.text}                            <div className="zhishi"></div>                        </div>                    );                } else {                    return (                        <div                            className="filter-item"                            onClick={() => {                                this.filterBarClick(item);                            }}                            ref={item.value}                            key={index}                            value={item.value}>                            {item.text}                        </div>                    );                }            })}        </div>    );};render(){  return(    <div>      ...      <div className="filter-content" style={{ display: this.state.filterBarShow }}>          {this.filterDom()}          <div className="shadow"></div>          {/* 按钮和占位 */}          <div              className="filte-btn-content"              onClick={() => {                  this.filterBtnClick();              }}>              <div className="filte-btn"></div>          </div>      </div>      ...    </div>  )}

scss样式表

.filter {  width: 100%;  // position: fixed;}.filter-content {    overflow: hidden;    padding-right: pxToRem(27px);    position: relative;    background: #fff;    .filter-list {        display: flex;        overflow-x: auto;        justify-content: space-between;        height: pxToRem(90px);        color: #333333;        align-items: center;        -webkit-overflow-scrolling: touch;        font-size: pxToRem(32px);        font-family:PingFangSC-Light,PingFang SC;        font-weight:300;        background: #fff;        margin-right: pxToRem(100px);        .filter-item {            text-align: center;            display: flex;            // flex-basis: 17px;            flex-shrink: 0;            white-space: nowrap;            padding: 0 pxToRem(25px);            background: #fff;            height: pxToRem(90px);            align-items: center;            justify-content: center;        }        .active{            font-size: pxToRem(36px);            font-weight: 600;            height: pxToRem(90px);            display: flex;            align-items: center;            justify-content: center;            position: relative;            flex: 1;            flex-direction: column;        }        .zhishi{            background: url("./../img/zhishi.png");            background-repeat: no-repeat;            background-size: 100%;            width: pxToRem(25px);            height: pxToRem(6px);            position: absolute;            bottom: pxToRem(10px);;            left: 50%;            transform: translate(-50%, 0);            z-index: 999;        }    }        .shadow{        height: pxToRem(90px);        width: pxToRem(133px);        position: absolute;        right: pxToRem(101px);        top: 0;        background:linear-gradient(270deg,rgba(255,255,255,1) 0%,rgba(255,255,255,0.14) 100%);        pointer-events: none;    }    .filte-btn{        background: url("./../img/shaixuan.png");        background-repeat: no-repeat;        background-size: 100%;        width: pxToRem(40px);        height: pxToRem(40px);    }    .filte-btn-content {        height: pxToRem(90px);        position: absolute;        right: pxToRem(27px);        top: 0;        background: #fff;        width: pxToRem(74px);        display: flex;        align-items: center;        justify-content: flex-end;    }}

实现

想要居中展示首先是需要找到中心点,然后在点击是计算偏移量,把对应的标签滚动到中心位置

filterBarClick = param => {        const { value, text } = param;        this.setState({            filterSelect: value        });        let dom = this.refs;        //获取点击时当前标签的DOM        let valDom = dom[value];        //获取标签父元素DOM        let contentDom = dom.filterBar;        //计算当前标签到最左侧的宽度        let valLeft = valDom.offsetLeft;        //计算当前标签本身的宽度        let valWidth = valDom.clientWidth;        //当前标签中心点到最左侧的距离        let valCenter = valLeft + valWidth / 2;        //可视屏幕宽度        let clientWidth = document.querySelector('body').offsetWidth;        //可视屏幕中心点(减去的30是列表两边的15像素的留白)        let center = (clientWidth - 30) / 2;        //计算当前标签中心点和屏幕中心点的偏移量 然后滚动相应的距离        if (valCenter > center) {            contentDom.scrollTo({                left: valCenter - center,                behavior: 'smooth'            });        } else {            contentDom.scrollTo({                left: 0,                behavior: 'smooth'            });        }    };