H5搜索历史自适应三行折叠(类似淘宝、京东)

2,617 阅读2分钟

想要实现以下功能:

  1. 历史内容长度自适应,一行显示不下添加省略号
  2. 搜索历史默认显示三行
  3. 如果超过三行则显示下拉更多按钮
  4. 点击下拉按钮显示更多记录

如下图所示:

话不多说,上代码 (移动端采用vant组件)

HTML布局

<div class="history-box">
  <div class="title">搜索历史</div>
  <ul class="history-content">
    <li v-for="(item, index) in historyDataShow" :key="index" @click="clickSearch(item)"><span>{{item}}</span></li>
    <li v-if="!showMoreHis && hasMoreBthHis" @click="toggleShowMoreHistory"><span><van-icon name="arrow-down"/></span></li>
    <li v-if="showMoreHis && hasMoreBthHis" @click="toggleShowMoreHistory"><span><van-icon name="arrow-up"/></span></li>
  </ul>
</div>

CSS样式(基于less)

.history-box {
  margin-bottom: .64rem;
}
.title {
  width: 100%;
  height: .45rem;
  line-height: .45rem;
  margin-top: .08rem;
  font-size: .32rem;
  font-weight: bold;
  color: #333;
}

ul {
  position: relative;

  li {
    display: inline-block;
    margin: .32rem .24rem 0 0;
    max-width: calc(100% - .24rem);
    height: .56rem;
    line-height: .56rem;
    text-align: center;
    font-size: .28rem;
    font-weight: 400;
    color: #999;
    background: #F5F5F5;
    border-radius: .29rem;
    cursor: pointer;

    span {
      display: block;
      margin: 0 .24rem;
      width: calc(100% - .46rem);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;

      .van-icon {
        vertical-align: middle;
      }
    }
  }
}

至此,布局和样式都已经OK,下面是逻辑代码

import localStore from '@/utils/localStore' //引入工具类-用于保存/提取历史记录

data(){
  return {
    hasMoreBthHis: false, //搜索历史是否显示 展开/收起 按钮
    historyData: [], //历史搜索数据
    historyDataShow: [], //历史搜索数据
  }
},
mounted() {
  this.historyDataShow = localStore.getItemAry('drug-chemical-query-history') //从内存中获取历史记录
  this.toggleHistoryData() //数据处理
},
methods:{
  //历史记录 页面超出三行截取数据
  toggleHistoryData() {
    let idx = 0
    let count = 0
    this.$nextTick(() => {
      let ulNode = document.querySelector('.history-content')

      if(ulNode != null) {
        let ulChid = ulNode.querySelectorAll('li') //获取父容器所有子节点
        ulChid.forEach((i, index) => {
          if (i.offsetLeft === 0) {
            count++
            if (count === 4) {
              idx = index - 1
              this.hasMoreBthHis = true
            }
          }
        })
      }
      // 超过2行截断数据
      if (idx > 0) {
        this.historyDataShow = this.historyData.slice(0, idx)
      } else {
        this.historyDataShow = this.historyData
      }
    })
  },
  //显示更多处理 - 历史搜索
  toggleShowMoreHistory() {
    this.showMoreHis = !this.showMoreHis
    if(this.showMoreHis) {
      this.historyDataShow = this.historyData
    } else {
      this.toggleHistoryData()
    }
  },
  //点击搜索按钮
  clickSearch(val){
    //本地存储搜索历史
    localStore.saveOrUpdateHistory('drug-chemical-query-history', val)
  },
}

附加:localStore工具类 - 内存中获取历史记录(这里内存中最多存储15条历史)

const localStore = {
  store: window.localStorage,
  //获取历史搜索记录
  getItemAry: function(key) {
    return eval(this.store.getItem(key))
  },
  //加入历史搜索 - 去重、按照搜索时间倒序、最多存15个
  saveOrUpdateHistory: function(key, value) {
    if(value != '' && value != null) {
      let localValue = this.getItemAry(key)

      if (localValue != null) {
        let index = localValue.indexOf(value)
        if (index > -1) {
          localValue.splice(index, 1)
        }
        localValue.unshift(value)
      } else {
        let ary = new Array()
        ary.push(value)
        localValue = ary
      }

      if(localValue && localValue.length > 15) {
        localValue = localValue.slice(0, 15)
      }

      this.setItem(key, localValue)
    }
  }
}
export default localStore