微信小程序折叠标签小记

245 阅读3分钟

微信小程序实现折叠标签

<view class="list-con list-con-3 {{dynamicClass}}">
  <view class="label" wx:for="{{labelArr}}" wx:key="index">{{item}}</view>
  <view class="btn expand-btn" wx:if="{{showExpandBtn}}" bindtap="changeExpand">
    <image class="search-key-item-deg" style="transform:rotate({{isExpand ? 180 : 0}}deg);" src="https://image.awehome.com/data/uploads/banner/20220608/5d7fb0844a8d467b23c991b5d9233f3b.png"></image>
  </view>
</view>
page {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  padding: 0 16px;
}

.title {
  text-align: center;
  margin: 40px auto 0;
}

.list-con {
  max-width: 375px;
  height: 70px;
  margin: 20px auto 0;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
}

.list-con-3 {
  height: 70px;
}

.list-expand {
  height: auto;
}

.search-key-item-deg {
  display: block;
  width: 25px;
  height: 25px;
}

.label,
.btn {
  max-width: 132px;
  max-width: calc(100% - 72px);
  height: 28px;
  border-radius: 50px;
  background: #f7f7f7;
  color: #1e1e1f;
  font-size: 12px;
  font-weight: 400;
  line-height: 28px;
  text-align: center;
  padding: 0 10px;
  margin: 0 8px 8px 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

.expand {
  width: 50px;
  font-size: 12px;
  color: #666;
  text-align: center;
  margin: 5px auto;
}

.expand-btn {
  max-width: 100px;
  margin-right: 0;
}

方法一:展开隐藏按钮和标签同级 - 通过高度判断

Page({
  data: {
    labelArr: [],
    baseArr: [],
    isExpand: false,
    showExpandBtn: false,
    labelLength: 0,
    hideLength: 0,
    dynamicClass: "",
  },

  initData() {
    let that = this;
    this.createSelectorQuery()
      .select(".list-con-3")
      .boundingClientRect((listConRect) => {
        this.createSelectorQuery()
          .selectAll(".label")
          .boundingClientRect((labels) => {
            let labelIndex = 0;
            const listConBottom = listConRect.bottom;

            for (let i = 0; i < labels.length; i++) {
              if (labels[i].top >= listConBottom) {
                this.setData({ showExpandBtn: true });
                labelIndex = i;
                break;
              }
            }

            if (!this.data.showExpandBtn) return;
            setTimeout(() => {
              that
                .createSelectorQuery()
                .select(".expand-btn")
                .boundingClientRect((expandBtnRect) => {
                  const expandBtnWidth = expandBtnRect.width;
                  for (let i = labelIndex - 1; i >= 0; i--) {
                    if (labels[i].right + expandBtnWidth <= listConRect.width) {
                      that.setData({
                        hideLength: i + 1,
                        labelArr: that.data.labelArr.slice(0, i + 1),
                      });
                      break;
                    }
                  }
                })
                .exec();
            }, 0);
          })
          .exec();
      })
      .exec();
  },

  changeExpand() {
    this.setData({
      isExpand: !this.data.isExpand,
      dynamicClass: this.data.isExpand ? "" : "list-expand",
    });
    if (this.data.isExpand) {
      this.setData({
        labelArr: this.data.baseArr,
        labelLength: this.data.baseArr.length,
      });
    } else {
      this.setData({
        labelArr: this.data.labelArr.slice(0, this.data.hideLength),
      });
    }
  },

  onLoad() {
    const labels = [
      "人工智能",
      "人工智能与应用",
      "行业分析与市场数据",
      "标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签标签",
      "标签A",
      "啊啊啊",
      "宝宝贝贝",
      "微信",
      "吧啊啊",
      "哦哦哦哦哦哦哦哦",
      "人工智能",
      "人工智能与应用",
    ];
    this.data.labelLength = labels.length;

    this.setData({
      baseArr: labels,
      labelArr: labels.slice(0, this.data.labelLength),
      labelLength: labels.length,
    });

    this.initData();
  },
});

方法二:展开隐藏按钮和标签同级 - 通过计算行数判断

Page({
  data: {
    labelArr: [],
    baseArr: [],
    isExpand: false,
    showExpandBtn: false,
    labelLength: 0,
    hideLength: 0,
    dynamicClass: "",
  },

  initData() {
    let that = this;
    const query = this.createSelectorQuery();
    query.select(".list-con-3").boundingClientRect();
    query.selectAll(".label").boundingClientRect();
    query.exec((res) => {
      if (!res || res.length < 2) return;
      const listCon = res[0]; // 容器
      const labels = res[1]; // 所有标签

      if (!labels || labels.length === 0) return;

      const firstLabelLeft = labels[0].left; // 第一个标签左侧位置
      let line = 0; // 记录当前行数
      let labelIndex = 0; // 记录超出的索引

      for (let i = 0; i < labels.length; i++) {
        if (labels[i].left === firstLabelLeft) {
          line += 1; // 发现新的一行
        }

        if (line > 2) {
          this.setData({
            showExpandBtn: true,
          });
          labelIndex = i;
          break;
        }
      }

      
      
      if (!this.data.showExpandBtn) return;

      setTimeout(() => {
        query.select(".expand-btn").boundingClientRect();
        query.exec((res2) => {
          if (!res2 || res2.length < 1) return;
          const expandBtn = res2[2]; // 获取展开按钮的信息
          if (!expandBtn) return;
          const expandBtnWidth = expandBtn.width; // 按钮宽度
          const labelMarginRight = 8; // 需要根据 wxss 设置 margin-right
          for (let i = labelIndex - 1; i >= 0; i--) {
            const labelRight = labels[i].right - listCon.left;
            if (
              labelRight + labelMarginRight + expandBtnWidth <=
              listCon.width
            ) {
              that.setData({
                hideLength: i + 1,
                labelLength: i + 1,
                labelArr: that.data.labelArr.slice(0, i + 1),
              });
              break;
            }
          }
        });
      }, 0);
    });
  },

  changeExpand() {
    this.setData({
      isExpand: !this.data.isExpand,
      dynamicClass: this.data.isExpand ? "" : "list-expand",
    });
    if (this.data.isExpand) {
      this.setData({
        labelArr: this.data.baseArr,
        labelLength: this.data.baseArr.length,
      });
    } else {
      this.setData({
        labelArr: this.data.labelArr.slice(0, this.data.hideLength),
      });
    }
  },

  onLoad() {
    const labels = [
      "人工智能",
      "人工智能与应用",
      "行业分析与市场数据",
      "标签标签标标签",
      "标签A",
      "啊啊啊",
      "宝宝贝贝",
      "微信",
      "吧啊啊",
      "哦哦哦哦哦哦哦哦",
      "人工智能",
      "人工智能与应用",
      "啊啊啊",
      "宝宝贝贝",
      "微信",
      "吧啊啊",
      "哦哦哦哦哦哦哦哦",
      "人工智能",
      "人工智能与应用",
    ];
    this.data.labelLength = labels.length;

    this.setData({
      baseArr: labels,
      labelArr: labels.slice(0, this.data.labelLength),
      labelLength: labels.length,
    });

    this.initData();
  },
});

参考文章

多行标签超出展开折叠功能