欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

React实现类似淘宝tab居中切换效果的示例代码

程序员文章站 2022-03-20 17:49:44
效果dom布局const label = { lettersort: false, paramname: "label", paramid: 0, title: "车源列表筛选项", option:...

效果

React实现类似淘宝tab居中切换效果的示例代码 

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

总结

到此这篇关于react实现类似淘宝tab居中切换效果的文章就介绍到这了,更多相关react tab居中切换内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!