自动循环滚动消息列表

参考链接:vue组件:列表自动无限循环_vue 列表循环滚动-CSDN博客

vue-seamless-scroll插件不完全适合项目应用场景。

封装组件auto-scroll

<template>
    <div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
      <div class="scroll-inner-box" ref="scrollBox">
        <div class="scroll-item-box" ref="scrollItemBox">
          <slot></slot>
        </div>
        <div v-if="showSecond" class="scroll-item-box">
          <slot></slot>
        </div>
      </div>
    </div>
  </template>
    <script>
  export default {
    name: "auto-scroll",
    props: {
      list: {
        type: Array,
        default: () => [
          { name: "张三1" },
          { name: "张三2" },
          { name: "张三3" },
          { name: "张三4" },
          { name: "张三5" },
          { name: "张三6" },
          { name: "张三7" },
          { name: "张三8" },
          { name: "张三9" },
          { name: "张三10" },
        ],
      },
      speed: {
        type: Number,
        default: 0.1,
      },
      //滚动作单步运动时的单纯运动距离
      singleHeight: {
        type: Number,
        default: 0,
      },
      //单步运动的时间间隔
      waitTime: {
        type: Number,
        default: 0,
      },
    },
    data() {
      return {
        rafId: null,
        y: 0,
        showSecond: false,
        controleHeight: 0,
      };
    },
    watch: {
      list: {
        handler(newVal) {
          var that = this;
          this.$nextTick(() => {
            console.log(newVal);
            if (newVal && newVal.length > 0) {
              let scrollBox = that.$refs.scrollBox;
              let outer = that.$refs.outer;
   
              if (this.myReq) {
                cancelAnimationFrame(this.myReq);
              }
              // 开启动画
              if (this.canRun()) this.reqAnimationFrame();
              // this.reqAnimationFrame();
              // 手动滚动到底部时滚动条重置到最上边,同时滚动盒子重置为top:0
              outer.addEventListener("scroll", function () {
                if (
                  outer.scrollTop + outer.clientHeight + 4 >=
                  outer.scrollHeight
                ) {
                  outer.scrollTop = 0;
                  that.y = 0;
                  scrollBox.style.top = 0;
                }
              });
            }
          });
        },
        deep: true,
        immediate: true,
      },
    },
    mounted() {
      window.addEventListener("resize", this.listenResizeFn);
    },
    methods: {
      listenResizeFn() {
        cancelAnimationFrame(this.myReq);
        if (this.canRun()) this.reqAnimationFrame();
      },
      onMouseover() {
        clearTimeout(this.timer);
        cancelAnimationFrame(this.myReq);
      },
      onMouseleave() {
        if (this.canRun()) this.reqAnimationFrame();
      },
      canRun() {
        let scrollItemBox = this.$refs.scrollItemBox;
        let scrollBox = this.$refs.scrollBox;
        let outer = this.$refs.outer;
        // 开启动画条件:滚动盒子(scrollBox)高度高于外层容器(outer)高度
        if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
          this.showSecond = false;
          outer.scrollTop = 0;
          this.y = 0;
          scrollBox.style.top = 0;
          return false;
        } else {
          this.showSecond = true;
          return true;
        }
      },
      //获取dom元素的高度:content+padding+margin+border
      getComputedHeight(dom) {
        let computedStyle = getComputedStyle(dom);
   
        let computedHeight =
          dom.offsetHeight +
          parseFloat(computedStyle.marginTop) +
          parseFloat(computedStyle.marginBottom);
        return computedHeight;
      },
      reqAnimationFrame() {
        //外层容器
        let outer = this.$refs.outer;
        //滚动盒子
        let scrollBox = this.$refs.scrollBox;
        //滚动盒子下边的第一个scroll-item-box,
        let scrollItemBox = this.$refs.scrollItemBox;
   
        //滚动速度
        this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
   
        //取第一个scrollItemBox高度
        let definedHeight = this.getComputedHeight(scrollItemBox);
        //持续滚动
        this.y = this.y + this.speed;
        scrollBox.style.top = -this.y + "px";
   
        //====添加滚动间隔控制====开始
        if (this.singleHeight >= 20 && this.waitTime > 500) {
          if (this.controleHeight >= this.singleHeight) {
            cancelAnimationFrame(this.myReq);
            this.controleHeight = 0;
            this.timer = setTimeout(() => {
              if (this.canRun) this.reqAnimationFrame();
            }, this.waitTime);
            return;
          } else {
            // 一次移动高度未达到指定距离继续执行动画
            this.controleHeight += this.speed;
          }
        }
        //====添加滚动间隔控制====结束
   
        //当滚动到第一个scroll-item-box高度时scrollBox重置为top:0,视觉上是无缝滚动
        if (this.y >= definedHeight) {
          this.y = 0;
        }
        this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
      },
    },
    destroyed() {
      window.removeEventListener("resize", this.listenResizeFn);
      cancelAnimationFrame(this.myReq);
      if (this.timer) clearTimeout(this.timer);
    },
  };
  </script>
    <style lang="less" scoped="scoped">
  .scroll-outer {
    height: 100%;
    overflow: hidden;
    // overflow-x: hidden;
    position: relative;
    &::-webkit-scrollbar {
      width: 0.3vw;
    }
    &:hover::-webkit-scrollbar-track {
      -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
      border-radius: 0.1vw;
      background-color: #295099;
      opacity: 1;
      display: none;
    }
    &:hover::-webkit-scrollbar-thumb {
      opacity: 1;
      border-radius: 0.1vw;
      -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
      background-color: #0ba9ea;
    }
  }
  .scroll-inner-box {
    height: auto;
    position: absolute;
    width: 100%;
    top: 0;
    left: 0;
  }
  </style>
    

使用:

<template>
  <div class="autoScroll">
    <autoScroll :list="recordMessages" :speed="0.5" :singleHeight="100">
      <div class="listItem" v-for = '(item,index) in recordMessages' :key="index+item">
        <span>{{item}}</span>
      </div>
    </autoScroll>
  </div>
</template>
    
<script>
import autoScroll from "../components/right/autoScroll.vue";
 
export default {
  components: {autoScroll},
  data() {
    return {
      recordMessages:[
        '消息消息消息消息消息消息消息消息消息消息消息111111111111111',
        '消息消息消息消息消息消息消息消息消息消息消息2222222222222222222222222',
        '消息消息消息消息消息消息消息消息消息消息消息333333333333333333333333333333333333333333333',
      ],
    };
  },
};
</script>
    
<style type="text/css" lang="less" scoped="scoped">
.autoScroll{
    height: calc(47% - 10px);
    padding: 0 10px;
    overflow: hidden;
    .listItem {
      width: 100%;
      background: rgba(69, 140, 201, 0.1);
      border-radius: 4px;
      margin-top: 10px;
      padding: 0px 10px 5px 10px;
      position: relative;
      animation: scroll 5s linear infinite; /* 设置动画 */
      span {
        font-weight: 400;
        font-size: 12px;
        text-align: left;
        color: #fff;
        opacity: 0.7;
      }
    }
}
</style>

效果:

消息滚动

注意:

  1. 参数waitTIme和singleHeight同时存在,才能出现滚动动画间隔执行的效果 
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Super ScrollView for UGUI提供基于UGUI ScrollRect的可轻松定制的ScrollView。它是一组C#脚本,可帮助您创建所需的ScrollView。这是非常强大的和高度优化的性能。 文件 Android演示应用程序 演示: - 聊天消息列表演示 - 水平画廊演示 - 垂直画廊演示 - GridView演示 - PageVew演示 - TreeVew演示 - 与稠粘头演示的TreeView - 旋转日期选择器 - 更改项目高度演示 - 下拉刷新演示 - 拉起来加载更多的演示 - 点击加载更多演示 - 选择并删除演示 - GridView删除项目演示 - 顶部到底部的演示 - 自下而上的演示 - 从左到右的演示 - 右侧演示 - 响应GridView演示 - TreeViewWithChildrenIndent演示 特征: - ListView和GridView和TreeView - 无限的项目 - 项目在不同的大小(高度/宽度) - 具有不同预制的物品 - 在初始时间大小未知的项目 - 垂直滚动视图(从上到下,从下到上) - 水平滚动视图(从左到右,从右到左) - 项目填充 - 滚动到指定的项目 - 滚动到具有偏移量的项目 - 项目计数在运行时更改 - 项目大小(高度/宽度)在运行时更改 - 物品捕捉到视口中的任何位置 - 项目循环,如微调 - 添加/删除项目 - 全部删除/删除所有项目 - 刷新并重新加载项目 - 使用池缓存项目,不要在运行时销毁项目 - 有效回收物品 - 平台无关 - UGUI支持 - 支持Unity平台(IOS / Android / Mac / PC / Console / Winphone / WebGL ...)
第1章 页面特效 1.1 HTML页面反向显示 1.2 页面自动最大化 1.3 页面自动刷新 1.4 页面的后退、刷新、前进 1.5保护网页源代码 1.6 保护自己的网页不被放入框架 1.7 保护自己的网页不被放入框架 1.8 打印页面的出错原因 1.9 当前网页调用其他网页 1.10 倒计时载入页面 1.11 定义网页的关键字 1.12 进入页面同时弹出欢迎对话框 1.13 禁止网页另存 1.14 禁止页面加入缓存 1.15 离开页面时弹出对话框 1.16 判断页面是否添加了W3C声明 1.17 屏蔽网页中的脚本 1.18 以频道模式打开页面 1.19 自动识别网页类型 1.20 在网页中动态添加Script脚本 1.21 用JavaScript随机修改页面的标题 1.22 判断网页加载完毕 1.23 嵌入网页的播放器 1.24 设置指定网页为主页 1.25 使用JavaScript传递页面参数 1.26 页面被冻结 第 2章 按钮特效 2.1 页面刷新按钮 2.2 按回车调用登录按钮 2.3 动态创建按钮 2.3 平面按钮 2.4 按钮的嵌入效果 2.5 按钮改变状态栏信息 2.6 定义按钮的热键 2.7 取得控件的绝对位置 2.8 删除时的确认提 示 2.9 按钮只能单击一次 2.10 防止按钮连击 2.11 图片式按钮 2.12 文字显示在按钮底部 2.13 选择不同的列表项就显示不同的按钮 2.14 使用按钮控制文本渐变 2.15 翻页效果的公告栏 2.16 动态设置控件的事件 第3章 字符串文本和输入框特效 3.1 只带下划线的输入框 3.2 限定文本框可输入字符数 3.3 文字过长的省略号 3.4 输出26个英文字母 3.5 首字母变为大写 3.6 textarea自适应文字行数 3.7 禁止文本框的拷贝和粘贴 3.8 控制两个文本框只输其一 3.9 判断编辑器中是否包含特殊字符 3.10 判断文本中回车的数量 3.11 判断字符串中有多少汉字 3.12 去除字符串的前后空格 3.13 刷新时清空所有文本框 3.14 随意改变大小的文本框 3.15 文本框的自动全选 3.16 文本框滚动导航 3.17 按钮获取焦点 3.18 文本框获取焦点弹出下拉框 3.19 文本框简单的单击效果 3.20 文字的打字效果 3.21 文字滚动 3.22 文字滑动 3.23 文字跳动特效 3.24 荧光效果的文本 3.25 文字逐个闪亮-霓虹灯效果 3.26 旋转式的变色文字特效 3.27 黑客帝国中的字符下落效果 3.28 获取表单中文本框的个数 3.29 光标停在文字最后 3.30 分行取textarea中的值 3.31 自动插入文本 3.32 选取textarea的指定行 3.33 文本放大镜 3.34 文本框的默认输入法 3.35 文本框显示网页中选中的内容 3.36 文字的垂直滚动 3.37 文字幻灯片 3.38 随机动态文字效果 3.39 实现textarea的自动滚动 3.40 使用marquee实现文字上下滚动 3.41 类似安装效果的textarea滚动 3.42 始终显示在最顶端的文本 3.43 JavaScript过滤SQL注入字符 3.44 textarea内实现行的翻页效果 3.45 textarea中的文本插入 3.46 查找两段文本中相同的词句 3.47 自动保存网页输出的文本 3.48 文本编辑器 第4章 鼠标特效 4.1 禁用鼠标右键 4.2 使鼠标滚轮失效 4.3 状态栏显示鼠标位置 4.4 点击鼠标右键到指定页 4.5 鼠标放到图片上会显示另外一张图片 4.6 鼠标形状定义大全 4.7 鼠标移入移出时颜色变化 4.8 跟随鼠标的文字 4.9 跟随鼠标的彩色文字 4.10 跟随鼠标的魔法文字 4.11 跟随鼠标的星星 4.12 跟随鼠标的旋转背景 4.13 图片跟随鼠标 4.14 围绕鼠标的文本 4.15 鼠标旁边的提示信息 4.16 鼠标移到下拉框时自动全部打开 4.17 checkbox鼠标移入移出的特效 第5章 层和框架的特效 5.1 div层提示效果 5.2 层自动滚动到最底端 5.3 div的自动滚动 5.4 div的折迭效果 5.5 圆角div 5.6 动态添加iframe框架 5.7 用层实现长文章分页 5.8 iframe自适应高度 5.9 类似MSN的消息提示 5.10 只打印iframe的内容 第6章 下拉列表特效 6.1 下拉框实现多选 6.2 实现两个select的同步 6.3 被选中的列表项下次不能再选 6.4 不带滚动条的select 6.5 从一个下拉列表往另一个下拉列表添加内容 6.6 改变列表项的上下顺序

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值