vue3实现无限循环滚动的方法;el-table内容无限循环滚动的实现

需求:vue3实现一个div内的内容无限循环滚动

方法一:

<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>

方法二:

<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>

方法三:

<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>

补充:el-table实现内容无限循环滚动方法:

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)
})

以上三种方法均能实现无限循环滚动,但是滚动的效果不是无缝衔接的,是滚动到最底部后直接闪现到内容顶部开始重新滚动;要想实现无缝衔接滚动,目前用js是难以实现的,为此花费了好长时间也没能实现,最后在bd中查到了可以实现这一功能的插件,比如vue3-seamless-scroll插件,具体的插件安装和使用可自行百度;

猜你喜欢

转载自blog.csdn.net/weixin_51747462/article/details/132778915