How to implement infinite loop scrolling in vue3; implementation of infinite loop scrolling of el-table content

Requirement: vue3 implements infinite loop scrolling of the content within a div

method one:

<template>
    <div id='container'>
        <div class="item" v-for=item in 5>测试内容{
   
   {
   
   { item }}</div>
    </div>
</template>

<script setup>
//封装一个方法
const fengzhuang = (containerId) => {
  let intervalId = null
    const container = document.getElementById(containerId)
    // console.log("container",container.scrollTop);
    const content = container.scrollHeight
    let containerHeight = container.clientHeight
    let containerScrollTop = container.scrollTop
    let currentScrollTop = 0;
    const startScrolling = () => {
      stopScrolling()

      intervalId = setInterval(() => {
        currentScrollTop += 1.5
          if(currentScrollTop >= content - containerHeight){
            currentScrollTop = 0
          }
          containerScrollTop = currentScrollTop;
          container.scrollTop = containerScrollTop;
      }, 50)
    }
    const stopScrolling = () => {
      clearInterval(intervalId)
    }
    const checkOverflow = () => {
      if (content > containerHeight) {
        startScrolling()
      } else {
        stopScrolling()
      }
    }
    checkOverflow()
}
//进入页面时执行这个方法
onMounted(()=> {
    fengzhuang('container')
})
</script>

Method Two:

<template>
    <div id='container'>
        <div id="content">
            <div id="scrollWrapper">
            <div class="item" v-for=item in 5>测试内容{
   
   {
   
   { item }}</div>
            </div>
        </div>
    </div>
</template>

<script setup>
//封装一个方法
let shouldScroll = ref(false)
const fengzhuang2 = (containerId,contentId,scrollWrapperId)=> {
  const container = document.getElementById(containerId)
  const content = document.getElementById(contentId)
  const scrollWrapper = document.getElementById(scrollWrapperId)

  const startScrolling = (scrollWrapper)=> {
      const scrollSpeed = 0.01;
      console.log("scrollWrapper.offsetHeight",scrollWrapper.offsetHeight);
      const contentHeight = scrollWrapper.offsetHeight;
      const containerHeight = container.offsetHeight;

      // 设置初始滚动位置
      scrollWrapper.style.transform = "translateY(0px)";
      // 启动动画
      scrollWrapper.animate([
        { transform: "translateY(0px)" },
        { transform: `translateY(-${contentHeight-320}px)` },
        // { transform: `translateY(-${containerHeight}px)` },
      ], {
        duration: (contentHeight + containerHeight) * scrollSpeed * 1000,
        easing: "linear",
        iterations: Infinity,
      });
    }
  if (content.offsetHeight > container.offsetHeight) {
        shouldScroll.value = true;
        startScrolling(scrollWrapper);
      }
}
//进入页面时执行这个方法
onMounted(()=> {
    fengzhuang2('container','content','scrollWrapper')
})
</script>

Method three:

<template>
  <div class="scroll-container">
    <div class="scroll-content" :style="contentStyle">
      <!-- 内容项 -->
      <div v-for="(item, index) in items" :key="index" class="scroll-item" >
        {
   
   { item }}
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, watchEffect } from "vue";

export default {
  setup() {
    const items = ref(["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"]); // 你的内容项数组
    const containerHeight = 200; // 调整滚动容器的高度
    const scrollSpeed = 0.5; // 调整滚动速度

    const contentStyle = ref({
      transform: "translateY(0)",
    });

    let currentIndex = 0;
    const contentHeight = items.value.length * 40; // 假设每个项的高度为40px

    const scrollFrame = () => {
      currentIndex += scrollSpeed;
      if (currentIndex >= contentHeight) {
        currentIndex = 0;
      }
      // const itemToMove = items.value.slice(parseInt(currentIndex/40))
      if(currentIndex % 40 == 0){
        // const itemToMove = items.value.slice(currentIndex/40)[0]; // 弹出第一个元素
        // const itemToMove = items.value.shift(); // 弹出第一个元素
        console.log("itemToMove");
        items.value.push(itemToMove); // 将弹出的元素放到数组末尾
      }
      contentStyle.value.transform = `translateY(-${currentIndex}px)`;
    };

    onMounted(() => {
      // 每帧滚动
      const scrollInterval = setInterval(scrollFrame, 15); // 16ms对应60帧每秒

      // 当滚动容器高度改变时,重新计算当前位置以实现无缝滚动
      watchEffect(() => {
        // currentIndex = currentIndex % contentHeight;
        contentStyle.value.transform = `translateY(-${currentIndex}px)`;
      });

      // 清除滚动定时器
      return () => clearInterval(scrollInterval);
    });

    return {
      items,
      contentStyle,
    };
  },
};
</script>

<style scoped>
.scroll-container {
  height: 40px; /* 调整滚动容器的高度 */
  overflow: hidden;
  border: 1px solid #ccc;
}

.scroll-content {
  display: flex;
  flex-direction: column;
  animation: scroll 5s linear infinite; /* 5秒完成一次滚动,可根据需要调整 */
}

.scroll-item {
  height: 40px; /* 每个滚动项的高度 */
  line-height: 40px;
  padding: 10px;
  background-color: #f0f0f0;
}

@keyframes scroll {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-100%);
  }
}
</style>

Supplement: el-table implements infinite loop scrolling method of content:

let scrollHeight = 0
let currentScrollTop = 0
let maxScrollTop = 0
let timeInter = null
let timeInter2 = null
const tableNode = ref<any>(null)

function updateList() {
  // 数据大于3条才会滑动
  if (tableData && tableData.value.length > 4) {
    // 获取滑动区域DOM 最新版本的element-plus节点有变化, 此版本为1.2.0-beta.3
    tableNode.value = tableRef.value.$refs.bodyWrapper.getElementsByClassName('el-scrollbar__wrap')[0]    // 设置每次滑动几行
    scrollHeight = tableNode.value.querySelectorAll('tr')[0].offsetHeight * 4
    // 设置每次滑动的PX和滑动区域的高度
    tableNode.value.style.height = `${scrollHeight}px`
    // 获取最大滑动空间
    maxScrollTop = tableNode.value.firstElementChild.offsetHeight - scrollHeight
    // 开始
    restTimeInter()
  }
}

function restTimeInter() {
  // 清除所有定时器
  clearAllInterval()
  // 设置定时器
  timeInter = setInterval(setMultiLine, 1500)
}
function clearAllInterval() {
  clearInterval(timeInter)
  clearInterval(timeInter2)
}
function setScrollTop() {
  tableNode.value.scrollTop++
  if (tableNode.value.scrollTop >= currentScrollTop) { // 达到下次应该滑动的位置
    clearInterval(timeInter2)
  }
  if (tableNode.value.scrollTop > maxScrollTop) { // 滑到底了
    tableNode.value.scrollTop = maxScrollTop
    clearInterval(timeInter2)
  }
}
function setMultiLine() {
  // 下次应该滑到哪
  currentScrollTop = (tableNode.value.scrollTop || 0) + scrollHeight + currentScrollTop % scrollHeight
  if (tableNode.value.scrollTop >= maxScrollTop) { // 滑完了 重置
    currentScrollTop = 0
    tableNode.value.scrollTop = 0
    restTimeInter()
  } else {
    // 清除上一个定时器
    clearInterval(timeInter2)
    // 开始滑
    timeInter2 = setInterval(setScrollTop, 10)
  }
}
onMounted(()=> {
      setTimeout(() => {
        updateList()
      }, 1000)
})

The above three methods can all achieve infinite loop scrolling, but the scrolling effect is not seamless. After scrolling to the bottom, it will flash directly to the top of the content and start scrolling again. To achieve seamless scrolling, it is currently difficult to achieve with js. Yes, it took a long time to achieve this, but finally I found a plug-in in bd that can achieve this function, such as the vue3-seamless-scroll plug-in. The specific plug-in installation and use can be found on Baidu;

Guess you like

Origin blog.csdn.net/weixin_51747462/article/details/132778915
Recommended