当前位置: 代码迷 >> 综合 >> React实现类似淘宝tab居中切换效果
  详细解决方案

React实现类似淘宝tab居中切换效果

热度:9   发布时间:2024-01-31 05:02:57.0

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 (<divref={item.value}className="filter-item active"key={index}value={item.value}>{item.text}<div className="zhishi"></div></div>);} else {return (<divclassName="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>{/* 按钮和占位 */}<divclassName="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;}
}

 

实现

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

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' }); } };" title="">

filterBarClick = param => {const { value, text } = param;this.setState({filterSelect: value});let dom = this.refs;//获取点击时当前标签的DOMlet valDom = dom[value];//获取标签父元素DOMlet 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'});}};

 

  相关解决方案