当数据发生变化时,无缝滚动怎么做。

407 阅读1分钟

前言: websocket推消息,数据发生变化,可以使用第三方库【swiper,vue-seamless-scroll等】. 就是下面圈起来的地方数据是变化的,当超过了2行,开始上下滚动,当由3行变为2行时,回到图片的样子。 image.png

先看HTML

就是2个v-for,一个是一行多少个,一个是一行显示的内容

      <ul class="content_right_patient">
        <li
          :data-list="row"
          v-for="(row, index) in rows"
          :key="row + index"
          :style="row % 2 ? 'background-color: #f1f2f2' : ''"
        >
          <div
            v-for="(item, index) in getPatientNameItems(row)"
            :key="item + index"
          >
            <span>
              {{ item }}
            </span>
          </div>
        </li>
      </ul>

模拟数据异步数据

  this.patientName = ["12", "13", "14", "15", "16", "17"];
  setTimeout(() => {
    this.patientName = ["12", "13", "14", "15", "16", "17", "18"];
  }, 2000);
  setTimeout(() => {
    this.patientName = [
      "13",
      "14",
      "15",
      "16",
      "17",
      "18",
      "19",
      "20",
      "12",
      "21",
    ];
  }, 6000);
  setTimeout(() => {
    this.patientName = ["12", "13", "15", "16", "17"];
  }, 10000);
  

动画部分

一个是开启动画,一个是关闭动画,这里我是通过监听rows变化去触发这2个函数,通过在页面上绑定的data-list来判断第一个数据应该插入到什么位置

async initAnimation() {
  if (this.animationFrame) {
    cancelAnimationFrame(this.animationFrame);
    // this.$forceUpdate();
  }
  await this.$nextTick();
  const ulBox = document.getElementsByClassName("content_right_patient")[0];
  console.log(ulBox);
  const lis = ulBox.getElementsByTagName("li");
  const liHeight = lis[0].offsetHeight;
  for (let i = 0; i < lis.length; i++) {
    lis[i].style.backgroundColor = "";
    lis[i].style.boxShadow = "rgba(0, 0, 0, 0.16) 0px 1px 4px";
  }
  const animationLoop = () => {
    this.scrollTop++;
    ulBox.scrollTop = this.scrollTop;
    // let computedStyle = window.getComputedStyle(ulBox); // 获取计算后的样式
    // const numTop = parseFloat(
    //   computedStyle.paddingTop.match(/^[0-9]+(\.[0-9]+)?/)[0]
    // );
    if (this.scrollTop >= liHeight) {
      let lastOneli = document.querySelectorAll(
        "li[data-list='" + this.rows + "']"
      )[0];
      const listNum = lis[0].getAttribute("data-list");
      if (listNum == 1) {
        ulBox.insertBefore(lis[0], lastOneli.nextSibling);
      } else {
        let slotLi = document.querySelectorAll(
          "li[data-list='" + (listNum - 1) + "']"
        )[0];
        ulBox.insertBefore(lis[0], slotLi.nextSibling);
      }
      this.scrollTop = 0;
    }
    this.animationFrame = requestAnimationFrame(animationLoop);
  };
  this.animationFrame = requestAnimationFrame(animationLoop);
},
async closeAnimation() {
  await this.$nextTick();
  if (this.animationFrame) {
    cancelAnimationFrame(this.animationFrame);
  }
  const ulBox = document.getElementsByClassName("content_right_patient")[0];
  const lis = ulBox.getElementsByTagName("li");
  for (let i = 0; i < lis.length; i++) {
    if (i % 2 === 0) {
      lis[i].style.backgroundColor = "#f1f2f3";
    }
    lis[i].style.boxShadow = "";
  }
  ulBox.scrollTop = 0;
  // this.$forceUpdate();
},