分享一个自己封装的数据无限滚动展示效果,鼠标移入暂停,移出继续

效果

数据无缝滚动

关键方法

 // 内容超出滚动展示
    setRoll() {
      let parentRoll = document.getElementById("parentRoll"); //获取外层div,外层div必须设置样式overflow: hidden;
      let roll = document.getElementById("roll"); // 获取里面需要滚动展示的div
      let parentH = parentRoll.clientHeight; // 获取外层div的高
      let rollH = roll.clientHeight; // 获取里面需要滚动展示div的高
      let scrollTop = parentRoll.scrollTop; // 获取外层div的scrollTop值(被遮住的高度)
      let scrollTopMax = rollH - parentH; // 结算scrollTop的最大值
      if (rollH > parentH) { // 判断如果外层div展示不下当前内容,就滚动起来展示
        this.timer = setInterval(() => { // 定时器增加scrollTop的值,调节定时大小可以控制滚动速度(scrollTop定时增加大小也可以控速)
          scrollTop += 1; // 定时增加
          scrollTop >= scrollTopMax && (scrollTop = 0);  // 滚动到了最大值(滚到低了),重新滚动 ---(可以把你要展示的数据复制一份,这样就可以实现循环无缝滚动了)
          parentRoll.scrollTop = scrollTop;
        }, 50);
      }
    },

记得给最外层div绑定鼠标移入停止滚动,移出继续滚动效果

// 鼠标移入移出
    mouseenter() {
      clearInterval(this.timer);
      console.log("鼠标移入了");
    },
    mouseleave() {
      this.setRoll();
      console.log("鼠标移出了");
    },

完整代码如下

<template>
  <div class="tab">
    <div class="tab-top">
      <div class="title">这里是标题</div>
      <div class="box">
        <div class="box-left">
          <div class="box-left-title">设备总数</div>
          <div class="box-left-icon">
            <img src="@/assets/icons/icon-01.png" alt="" />
          </div>
          <div class="box-left-numb">9999</div>
        </div>
        <div class="box-right">
          <div class="box-right-title">设备总数</div>
          <div class="box-right-icon">
            <img src="@/assets/icons/icon-02.png" alt="" />
          </div>
          <div class="box-right-numb">9999</div>
        </div>
      </div>
    </div>
    <div class="tab-bottom">
      <div class="title">温湿度列表</div>
      <div class="box">
        <div class="box-top">
          <div>
            <div class="icon">
              <img src="@/assets/icons/温度.png" alt="" />
            </div>
            <div style="color: #ffce1a" class="describe">
              <div>{{hold.t}} ℃</div>
              <div>温度</div>
            </div>
          </div>
          <div>
            <div class="icon">
              <img src="@/assets/icons/湿度.png" alt="" />
            </div>
            <div class="describe">
              <div>{{hold.s}} %</div>
              <div>湿度</div>
            </div>
          </div>
        </div>
        <div class="box-bottom">
          <div class="head">
            <div v-for="(item, i) in tabData.head" :key="i">
              {{ item.name }}
            </div>
          </div>
          <div
            class="body"
            ref="roll"
            id="parentRoll"
            @mouseenter="mouseenter"
            @mouseleave="mouseleave"
          >
            <div ref="roll" id="roll">
              <div
                class="body-list"
                v-for="(list, i) in tabData.body"
                :key="i"
                :style="{
                  background: i % 2 === 1 ? 'rgba(16, 35, 103, 0.5)' : '',
                }"
                @click="clickLine(i)"
              >
                <div
                  v-for="(item, j) in tabData.head"
                  :key="j"
                  :style="{
                    background: list.flag ? '#1d327e' : '',
                    color: list.flag ? '#5fdef6' : '',
                  }"
                >
                  {{ list[item.key] }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import elementResizeDetectorMaker from "element-resize-detector";
export default {
  data() {
    return {
      tabData: {
        head: [
          { name: "实验名称", key: "a" },
          { name: "温度范围", key: "b" },
          { name: "湿度范围", key: "c" },
          { name: "时间", key: "d" },
        ],
        body: [
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "34",
            s: "53",
            flag: true,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "37",
            s: "78",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "35",
            s: "66",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "40",
            s: "55",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "38",
            s: "93",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "30",
            s: "88",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "30",
            s: "88",
            flag: false,
          },
           {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "37",
            s: "78",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "35",
            s: "66",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "40",
            s: "55",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "38",
            s: "93",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "30",
            s: "88",
            flag: false,
          },
          {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "30",
            s: "88",
            flag: false,
          },
        ],
      }, // 表数据
      timer: null, // 滚动定时器
      hold: {
            a: "aaa实验室",
            b: "30 - 45",
            c: "0%-100%",
            d: "2023-03-12",
            t: "34",
            s: "53",
            flag: true,
          }, // 暂存点击行的数据
    };
  },
  methods: {
    // 点击行
    clickLine(index) {
      this.tabData.body = this.tabData.body.map((item, i) => {
        if (i === index) {
          item.flag = true;
          this.hold = item
        } else {
          item.flag = false;
        }
        return item;
      });
    },
    // 内容超出滚动展示
    setRoll() {
      let parentRoll = document.getElementById("parentRoll"); //获取外层div,外层div必须设置样式overflow: hidden;
      let roll = document.getElementById("roll"); // 获取里面需要滚动展示的div
      let parentH = parentRoll.clientHeight; // 获取外层div的高
      let rollH = roll.clientHeight; // 获取里面需要滚动展示div的高
      let scrollTop = parentRoll.scrollTop; // 获取外层div的scrollTop值(被遮住的高度)
      let scrollTopMax = rollH - parentH; // 结算scrollTop的最大值
      if (rollH > parentH) { // 判断如果外层div展示不下当前内容,就滚动起来展示
        this.timer = setInterval(() => { // 定时器增加scrollTop的值,调节定时大小可以控制滚动速度(scrollTop定时增加大小也可以控速)
          scrollTop += 1; // 定时增加
          scrollTop >= scrollTopMax && (scrollTop = 0);  // 滚动到了最大值(滚到低了),重新滚动 ---(可以把你要展示的数据复制一份,这样就可以实现循环无缝滚动了)
          parentRoll.scrollTop = scrollTop;
        }, 50);
      }
    },
    // 鼠标移入移出
    mouseenter() {
      clearInterval(this.timer);
      console.log("鼠标移入了");
    },
    mouseleave() {
      this.setRoll();
      console.log("鼠标移出了");
    },
    // 视口变化了,要重新执行滚动方法
    outSize() {
      let erd = elementResizeDetectorMaker();
      erd.listenTo(this.$refs.roll, () => {
        this.timer && clearInterval(this.timer);
        this.setRoll();
      });
    },
  },
  mounted() {
    this.outSize();
  },
  computed: {
   
  },
  destroyed() {},
};
</script>

<style lang='scss' scoped>
.tab {
  font-size: 0.18rem;
  height: 100%;
  &-top {
    height: 30%;
    .title {
      height: 0.45rem;
      display: flex;
      align-items: center;
      font-size: 0.2rem;
      font-weight: 500;
      background-color: #1d327e;
      color: #5fdef6;
    }
    .box {
      height: calc(100% - 0.45rem);
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      &-left {
        padding: 0.1rem;
        width: 40%;
        height: 95%;
        color: #b5b915;
        font-weight: bold;
        background-image: url("@/assets/icons/iconBj1.png");
        background-size: 100% 100%;
        &-title {
          height: 30%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        &-icon {
          height: 40%;
          display: flex;
          justify-content: center;
          align-items: center;
          & > img {
            height: 100%;
          }
        }
        &-numb {
          height: 30%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
      &-right {
        padding: 0.1rem;
        color: #1fee3c;
        font-weight: bold;
        width: 40%;
        height: 95%;
        background-image: url("@/assets/icons/iconBj1.png");
        background-size: 100% 100%;
        &-title {
          height: 30%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        &-icon {
          height: 40%;
          display: flex;
          justify-content: center;
          align-items: center;
          & > img {
            height: 100%;
          }
        }
        &-numb {
          height: 30%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
    }
  }
  &-bottom {
    height: 70%;
    .title {
      height: 0.45rem;
      display: flex;
      align-items: center;
      font-size: 0.2rem;
      font-weight: 500;
      background-color: #1d327e;
      color: #5fdef6;
    }
    .box {
      height: calc(100% - 0.45rem);
      &-top {
        height: 25%;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        & > div {
          width: 45%;
          height: 90%;
          color: #37e2f4;
          padding: 0 0.2rem;
          background-image: url("@/assets/icons/iconBj2.png");
          background-size: 100% 100%;
          display: flex;
          .icon {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            & > img {
              width: 40%;
            }
          }
          .describe {
            flex: 2;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
          }
        }
      }
      &-bottom {
        height: 75%;
        padding-top: 0.08rem;
        .head {
          display: flex;
          color: #5fdef6;
          height: 0.45rem;
          background-color: #1d327e;
          & > div {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }
        .body {
          cursor: pointer;
          overflow: hidden;
          height: calc(100% - 0.45rem);
          color: #9aa2c8;
          font-size: 0.16rem;
          &-list {
            height: 0.4rem;
            display: flex;
            & > div {
              flex: 1;
              display: flex;
              align-items: center;
              justify-content: center;
            }
          }
        }
      }
    }
  }
}
</style>

,可复制粘贴看效果

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值