【性能优化】在大批量数据下使用 HTML+CSS实现走马灯,防止页面卡顿(二)

news2024/11/16 3:26:38

在这里插入图片描述

上一篇只是简单演示了’下一张’的操作和整体的设计思路,这两天把剩余功能补全了,代码经过精简,可封装当成轮播组件使用,详细如下.

代码

<template>
    <div class="container">

        <button @click="checkNext('last')">上一张</button>
        <button @click="checkNext('next')">下一张</button>
        <div class="windows" @mousemove="stopPlay" @mouseleave="autoPlay">
            <div class="scrollBox">
                <div class="scrollItem">
                    <div class="img">
                        <el-image :src="initialData.imgUrl"></el-image>
                    </div>
                    <div class="messBox">{{ initialData.mess }}</div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
  data () {
    return {
      localData: [
        { imgUrl: '', mess: '11111' },
        { imgUrl: '', mess: '2222' },
        { imgUrl: '../assets/dz.png', mess: '3333' },
        { imgUrl: '../assets/logo.png', mess: '44444' },
        { imgUrl: '', mess: '55555' },
        { imgUrl: '', mess: '66666' }
      ],
      initialData: '', // 初始展示数据
      nowIndex: 0, // 当前展示数据的索引
      progressControler: false, // 控制切换的变量
      autoPlayTimer: '', // 自动播放定时器id
      nextShowData: { imgUrl: '', mess: '' }// 下一批展示的数据
    }
  },
  mounted () {
    this.initData()
  },
  beforeRouteLeave (to, from, next) {
    // 清除定时器
    clearInterval(this.autoPlayTimer)
    console.log('离开当前页面')
    next()
  },
  methods: {
    initData () {
      // 初始赋值
      this.initialData = this.localData[this.nowIndex]
      // 自动播放
      this.autoPlay()
    },

    // 查看上一张/下一张
    checkNext (type) {
      // 信息展示列表无数据或只有一条数据时,不执行
      if (!this.localData || this.localData.length <= 1) return
      // 防止猛点
      if (this.progressControler) {
        console.log('当前操作过快')
        return
      }
      this.progressControler = true // 将当前操作进程锁死,完成后才允许下一次操作
      this.readyBox(type)// 准备新的dom元素
      let removeDomIndex = ''
      let createDomIndex = ''
      if (type === 'last') {
        console.log('查看上一张')
        removeDomIndex = 1
        createDomIndex = 0
        this.nowIndex--
        if (this.nowIndex < 0) { this.nowIndex = this.localData.length - 1 }// 循环播放
      }
      if (type === 'next') {
        console.log('查看下一张')
        removeDomIndex = 0
        createDomIndex = 1
        this.nowIndex++
        if (this.localData.length < this.nowIndex + 1) { this.nowIndex = 0 }// 循环播放
      }
      // 获取dom,准备移动和删除节点
      const fatherDom = document.querySelector('.windows')
      const moveDistanceX = fatherDom.offsetWidth
      const domArr = fatherDom.querySelectorAll('.scrollBox')

      // 根据类名判断要移除的子盒子的偏移值
      const isRealDom = domArr[removeDomIndex].classList.contains('newScrollBox')
      const isRightCreatDom = domArr[removeDomIndex].classList.contains('RightnewScrollBox')
      const isLeftCreatDom = domArr[removeDomIndex].classList.contains('LeftnewScrollBox')

      // 实现走马灯移动效果
      if (!isRealDom) {
        domArr[removeDomIndex].style.transform = `translate(${type === 'next' ? -moveDistanceX : moveDistanceX}px,0px)`
      }

      if ((type === 'next' && isRightCreatDom) || (type === 'last' && isLeftCreatDom)) {
        domArr[removeDomIndex].style.transform = `translate(${type === 'next' ? -moveDistanceX * 2 : moveDistanceX * 2}px,0px)`
      }
      if ((type === 'next' && isLeftCreatDom) || (type === 'last' && isRightCreatDom)) {
        domArr[removeDomIndex].style.transform = 'translate(0px,0px)'
      }
      domArr[createDomIndex].style.transform = `translateX(${type === 'next' ? -moveDistanceX : moveDistanceX}px)`

      const timeId1 = setTimeout(() => {
        fatherDom.removeChild(domArr[removeDomIndex])
        this.progressControler = false // 允许进行下一次操作
        clearTimeout(timeId1)
      }, 501)
    },

    // 为下一次移动准备dom元素
    readyBox (type) {
      let nextShowData = ''// 上一张或下一张要展示的数据
      const fatherDom = document.querySelector('.windows')// 获取父元素
      const newDom = document.createElement('div')// 创建新元素
      // 设置新元素的样式
      newDom.className = 'scrollBox'
      newDom.classList.add('newScrollBox')
      newDom.style.width = '100%'
      newDom.style.height = '100%'
      newDom.style.position = 'absolute'
      newDom.style.transition = 'all 0.5s'

      // 上一张
      if (type === 'last') {
        // 确定下一条播放数据的取值
        if (this.nowIndex === 0) {
          nextShowData = this.localData[this.localData.length - 1]
        } else {
          nextShowData = this.localData[this.nowIndex - 1]
        }
        newDom.style.left = '-100%'
        newDom.classList.add('LeftnewScrollBox')
        // 插入子元素
        newDom.innerHTML = manageHtml(nextShowData)
        fatherDom.insertBefore(newDom, fatherDom.firstChild)
      }
      // 下一张的数据
      if (type === 'next') {
        // 确定下一条播放数据的取值
        if (this.localData.length === this.nowIndex + 1) {
          nextShowData = this.localData[0]
        } else {
          nextShowData = this.localData[this.nowIndex + 1]
        }

        newDom.style.left = '100%'
        newDom.classList.add('RightnewScrollBox')

        // 插入子元素
        newDom.innerHTML = manageHtml(nextShowData)
        fatherDom.appendChild(newDom)
      }

      // 管理动态页面结构
      function manageHtml (nextShowData) {
        // 新元素的内部结构
        const innerHtml = `
                <div class="scrollItem" style=" display: flex;  width: 100%; height: 100%; background-color: pink;">
                    <div class="img" style="width:50%; height:100%" >
                        <el-image src="${nextShowData.imgUrl}"></el-image>
                    </div>
                    <div class="messBox" style=" font-size: 16px; width:50%; height:100%; background-color: skyblue; ">
                        ${nextShowData.mess}
                    </div>
                </div>
        `
        return innerHtml
      }
    },
    // 自动播放
    autoPlay () {
      this.autoPlayTimer = setInterval(() => {
        this.checkNext('next')
      }, 3000)
    },

    // 暂停播放
    stopPlay () {
      if (this.progressControler) {
        console.log('鼠标移入时进程被打断')
        this.progressControler = !this.progressControler
      }
      clearInterval(this.autoPlayTimer)
    }
  }
}
</script>
<style lang='scss' scoped>
.container {
    width: 100%;
    height: 100%;
}

.container .windows {
    position: relative;
    left: 30%;
    top: 30%;
    font-size: 0px;
    overflow: hidden;
    width: 40%;
    height: 40%;
}

.scrollBox {
    position: absolute;
    width: 100%;
    height: 100%;
    transition: all 0.5s;
}

.windows .scrollItem {
    display: flex;
    width: 100%;
    height: 100%;
    background-color: pink;
}

.windows .scrollItem .img {
    width: 50%;
    height: 100%;
}

.windows .messBox {
    font-size: 16px;
    width: 50%;
    height: 100%;
    background-color: skyblue;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1950507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++之栈和队列使用及模拟实现

目录 栈的使用 队列的使用 栈的模拟实现 队列的模拟实现 deuqe容器介绍 在C语言中我们已经学习了栈和队列的相关性质&#xff0c;今天我们主要来学习C语法中栈和队列的相关概念。 栈的使用 在C中栈是一种容器适配器&#xff0c;在其内部适配了其它的容器&#xff0c;其相…

go程序在windows服务中优雅开启和关闭

本篇主要是讲述一个go程序&#xff0c;如何在windows服务中优雅开启和关闭&#xff0c;废话不多说&#xff0c;开搞&#xff01;&#xff01;&#xff01;   使用方式&#xff1a;go程序 net服务启动 Ⅰ 开篇不利 Windows go进程编译后&#xff0c;为一个.exe文件,直接执行即…

使用api 调试接口 ,配置 Header 、 body 远程调试 线上接口

学习目标&#xff1a; 目标 使用api 调试接口 &#xff0c;配置 Header 、 body 远程调试 线上接口 学习内容&#xff1a; 内容 设置请求方式 2. 选择 POST 提交 3.设置 Header 一般默认的 4个 header 属性就可以直接使用&#xff0c;如有特殊情况&#xff0c;需进行属性设…

Docusaurus VS VuePress:哪一个更适合你的技术文档?

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

springcloud接入seata管理分布式事务

下载安装包 链接: seata 配置seata-server 文件上传Linux解压 压缩包我放在/usr/local/seata中 tar -zxvf seata-server-2.0.0.tar.gz修改配置文件 设置nacos为注册和配置中心 进入文件夹 cd /usr/local/seata/seata/conf修改application.yml文件 ...... ...... cons…

关键词查找【Aho-Corasick 算法】

【全程干货】程序员必备算法&#xff01;AC自动机算法敏感词匹配算法&#xff01;动画演示讲解&#xff0c;看完轻松掌握&#xff0c;面试官都被你唬住&#xff01;&#xff01;_哔哩哔哩_bilibili 著名的多模匹配算法 引入依赖&#xff1a; <dependency><groupId>…

ICMPv6与DHCPv6之网络工程师软考中级

ICMPv6概述 ICMPv6是IPv6的基础协议之一。 在IPv6报文头部中&#xff0c;Next Header字段值为58则对应为ICMPv6报文。 ICMPv6报文用于通告相关信息或错误。 ICMPv6报文被广泛应用于其它协议中&#xff0c;包括NDP、Path MTU发现机制等 ICMPv6控制着IPv6中的地址自动配置、地址…

前端知识--前端访问后端技术Ajax及框架Axios

一、异步数据请求技术----Ajax Ajax是前端访问后端的技术&#xff0c;为异步请求&#xff08;不刷新页面&#xff0c;请求数据&#xff0c;只更新局部数据&#xff09;。 例如&#xff1a;在京东网站中搜索电脑&#xff0c;就会出现一些联想搜索&#xff0c;但此时页面并没有…

AI行业合适做必应bing推广吗?怎么开户呢?

快速发展的AI行业中&#xff0c;有效的市场获客渠道是关键&#xff0c;随着数字营销领域的不断演进&#xff0c;必应Bing以其独特的市场定位、庞大的用户基础和高效的广告系统&#xff0c;成为AI企业推广策略中的重要一环。特别是针对那些寻求精准触达、高效转化的AI企业而言&a…

2024国际燃气轮机运维周线上分享第一期开启!共探燃机新生态

为促进国内重型燃气轮机运维技术发展&#xff0c;加快建立独立自主的燃气轮机运维技术体系&#xff0c;2024国际燃气轮机运维大会将于2024年10月17-18日在中国广州盛大召开&#xff01; 2024国际燃气轮机运维大会将通过线上直播会议、线下技术分享及颁奖典礼等形式展开&#xf…

血泪史!ora-00600 16305报错解决过程

一个客户重启操作系统后数据库启动不了,检查日志发现报错ORA-00600 [16305] 在MOS中找了一下,发现说是loopback地址不通: 测试了一下ping 127.0.0.1不通. 再次多次尝试发现登录到服务器上面,在本机上ping 127 localhost 本机实际地址 都不通,但是其它服务器可以ping通他的…

W30-python03-迭代器和生成器

迭代器&#xff1a;迭代是Python最强大的功能之一&#xff0c;是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问&#xff0c;直到所有的元素被访问完结束。迭代器只能往前不会后退。 迭代器有两个基本的方法&#xff1a;iter() 和 next()。 生成器&#xff1…

Godot入门 05收集物品

创建新场景&#xff0c;添加Area2D节点&#xff0c;AnimatedSprite2D节点 &#xff0c;CollisionShape2D节点 添加硬币 按F键居中&#xff0c;放大视图。设置动画速度设为10FPS&#xff0c;加载后自动播放&#xff0c;动画循环 碰撞形状设为圆形&#xff0c;修改Area2D节点为Co…

Java---后端文件上传详解

袁门才俊志高远&#xff0c; 震古烁今意决然。 风采翩翩才情显&#xff0c; 雄姿英发立世间。 目录 一&#xff0c;简单案例演示 二&#xff0c;服务器本地存储 三&#xff0c;配置单个文件上传大小限制 一&#xff0c;简单案例演示 首先简单编写一个前端网页&#xff1a; &l…

scrapy 爬取旅游景点相关数据(一)

第一节 Scrapy 练习爬取穷游旅游景点 配套视频可以前往B站&#xff1a;https://www.bilibili.com/video/BV1Vx4y147wQ/?vd_source4c338cd1b04806ba681778966b6fbd65 本项目为scrapy 练手项目&#xff0c;爬取的是穷游旅游景点列表数据 0 系统的环境 现在网上可以找到很多scr…

java基础概念05-运算符

一、自增自减运算符 二、赋值运算符 2-1、注意 三、关系运算符 四、逻辑运算符 4-1、短路逻辑运算符 五、三元运算符 六、运算符的优先级

PostgreSQL 中如何重置序列值:将自增 ID 设定为特定值开始

我是从excel中将数据导入&#xff0c;然后再通过sql插入数据&#xff0c;就报错。 需要设置自增ID开始值 1、确定序列名称&#xff1a; 首先&#xff0c;需要找到与的增字段相关的序列名称。假设表名是 my_table 和自增字段是 id&#xff0c;可以使用以下查询来获取序列名称…

嵌入式C++、Raspberry Pi、LoRa和Wi-Fi技术、TensorFlow、ROS/ROS2:农业巡检数据导航机器人设计流程(代码示例)

随着科技的不断进步&#xff0c;农业领域也在逐渐向智能化发展。农业巡检机器人作为农业智能化的重要组成部分&#xff0c;能够自动化地监测农作物生长状况&#xff0c;提高农业管理的效率和精确度。本文将介绍一个基于Raspberry Pi和NVIDIA Jetson的农业巡检机器人&#xff0c…

华天动力OA downloadWpsFile接口处任意文件读取漏洞复现 [附POC]

文章目录 华天动力OA downloadWpsFile接口处任意文件读取漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现华天动力OA downloadWpsFile接口处任意文件读取漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内…

学习日记:输入输出

目录 1.概念 2. C语言函数库提供的输入输出函数 2.1 getchar 2.2 putchar 2.3 printf 附&#xff1a;占位符 2.4 scanf 3. 附加 1.概念 输入是从键盘、鼠标等设备向计算机&#xff08;内存&#xff09; 注&#xff1a;c语言本身不提供输入输出功能&#xff0c;使用的…