〖大前端 - 基础入门三大核心之JS篇㊻〗- JS + CSS实现动画

news2025/1/18 11:45:25
  • 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费如需要项目实战或者是体系化资源,文末名片加V!
  • 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
  • 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker全栈领域优质创作者

  • 🏆 白宝书系列
    • 🏅 启示录 - 攻城狮的自我修养
    • 🏅 Python全栈白宝书
    • 🏅 ChatGPT实践指南白宝书
    • 🏅 产品思维训练白宝书
    • 🏅 全域运营实战白宝书
    • 🏅 大前端全栈架构白宝书


文章目录

  • ⭐ JS+CSS实现动画
  • ⭐ 无缝连续滚动特效开发
  • ⭐ 跑马灯轮播图特效开发
  • ⭐ 呼吸轮播图特效开发

⭐ JS+CSS实现动画

我们已经知道CSS3的transition过渡属性可以实现动画,而JavaScript可以利用这一属性轻松的实现元素的动画,并且JSS和CSS3结合可以规避利用定时器实现动画的缺点。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box {
            width: 100px;
            height: 100px;
            background-color: orange;
            position: absolute;
            top: 100px;
            left: 100px;
        }
    </style>
</head>
<body>
    <button id="btn">开始运动</button>
    <div id="box"></div>

    <script>
        var oBtn = document.getElementById('btn');
        var oBox = document.getElementById('box');

        var pos = 1; //1左边,2右边

        oBtn.onclick = function () {
            //加上过渡属性,即可实现缓动效果
            oBox.style.transition = 'all 2s linear 0s';
            if (pos == 1) {
                //如果盒子在左边,让它的移动到右边
                oBox.style.left = 500 + 'px';
                pos = 2;
            }else {
                //如果盒子在右边,让它移动到左边
                oBox.style.left = 100 + 'px';
                pos = 1;
            };
        };

    </script>
</body>
</html>

20230424_18410820234241842351

上述案例可以看到,每次点击“开始运动”按钮,不管盒子有没有移动到重点,盒子的运动方向都会改变。在很多情况下,我们需要控制当某个“动作”结束后,才能进行下一次的点击。这就需要用到函数节流

**函数节流:**一个函数执行一次后,只有大于设定的执行周期才允许执行第二次。

函数节流需要借助延时器:setTimeout()

函数节流的公式:

var lock = true;

function 需要节流的函数() {
    //如果锁是关闭状态,则不执行
    if (!lock) return;
    //函数核心语句

    //关锁
    lock = false;

    //指定毫秒数后将锁打开
    setTimeout(function () {
        lock = true;
    }, 2000);
}

利用函数节流优化一下上面案例中的代码:

<body>
    <button id="btn">开始运动</button>
    <div id="box"></div>

    <script>
        var oBtn = document.getElementById('btn');
        var oBox = document.getElementById('box');

        var pos = 1; //1左边,2右边
        var lock = true; //函数节流锁

        oBtn.onclick = function () {
            //判断如果锁是关闭的,则直接return,不执行下面的程序
            if (!lock) return;

            oBox.style.transition = 'all 2s linear 0s';
            if (pos == 1) {
                //如果盒子在左边,让它的移动到右边
                oBox.style.left = 500 + 'px';
                pos = 2;
            }else {
                //如果盒子在右边,让它移动到左边
                oBox.style.left = 100 + 'px';
                pos = 1;
            };

            //关锁
            lock = false;
            //2s后将锁打开,因为过渡的时间是2s,所以2s后盒子会到到达终点
            setTimeout(function name(params) {
                lock = true;
            }, 2000);
        };
    </script>

20230424_1901552023424198382

使用函数节流优化了代码之后,在盒子还没有运动到终点时,再次点击按钮不会改变盒子的运动方向,只有盒子运动到终点,再次点击盒子才能返回。

⭐ 无缝连续滚动特效开发

比如下面这个网站上就有一个“无缝连续滚动特效”,“最新播报”栏目中的新闻点连续不断的持续从右向左循环滚动。下面就来动手实现一个这样的案例。

image-20230425101336629

案例: 实现下面的无缝连续滚动特效,

题目分析:滚动其实就是元素在盒子内向左移动,盒子设置overflow:hidden使盒子外侧的部分隐藏。要达到无缝连续滚动的效果,不可能设置无限多的元素,这里用到一个视觉欺骗的小技巧,用js复制一组元素,当第一组元素完全移出盒子时,把第一组的元素的位置再调整回来继续向左移动,这样就实现了“连续滚动”的效果。用定时器就可以实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .box {
            width: 1000px;
            height: 200px;
            border: 1px solid #000;
            margin: 50px auto;
            overflow: hidden;
        }

        .box ul {
            width: 3000px;
            list-style: none;
            position: relative;
        }

        .box ul li {
            float: left;
            margin-right: 10px;
        }
    </style>
</head>

<body>
    <div id="box" class="box">
        <ul id="list">
            <li><img src="/images/husky1_little.png" alt=""></li>
            <li><img src="/images/husky2_little.jpg" alt=""></li>
            <li><img src="/images/husky3_little.jpg" alt=""></li>
            <li><img src="/images/husky4_little.jpg" alt=""></li>
        </ul>
    </div>

    <script>
        var oBox = document.getElementById('box');
        var oList = document.getElementById('list');
        oList.innerHTML += oList.innerHTML;  //复制一份图片插入ul里面

        //定义全局变量
        var left = 0;
        var timer;
		
        move(); //一开始先进行滚动
        //将滚动封装成函数,方便调用
        function move() {
            //设表先关(设置一个定时器,先关掉它)
            clearInterval(timer);
            //设置定时器
            timer = setInterval(function () {
                left -= 2;
                //当到达最左侧时,返回到原点继续移动,制造滚动的视觉效果
                if (left <= -857) {
                    left = 0;
                };
                oList.style.left = left + 'px';
            }, 20);
        };
        //鼠标移动到上面,停止滚动
        oBox.onmouseover = function () {
            clearInterval(timer);
        };
        //鼠标移开,继续滚动
        oBox.onmouseleave = function () {
            move();
        };
    </script>
</body>
</html>

20230425_11362020234251137511

记住一个口诀:设表先关,即设置定时器前,先调用clearInterval()方法关闭定时器,防止用户频繁的触发定时器 ,导致定时器出现叠加现象。

⭐ 跑马灯轮播图特效开发

实现下面效果的轮播图,点击左右两边的按钮,实现图片左右滚动循环切换

20230425_1549142023425155122

题目分析:给左右两个按钮添加事件监听,类似上篇中的无缝连续滚动特效,点击按钮时更改ul的left属性,实现图片向左/向右移动。

难点:

  1. 向右切换到最后一张图片,再次点击时,如果无缝切换到第一张图片。
  2. 第一张图片向左切换时,如果无缝切换到最后一张图片。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .carousel {
            width: 1202px;
            height: 800px;
            border: 1px solid #000;
            margin: 100px auto;
            position: relative;
            overflow: hidden;
        }

        .carousel ul {
            position: absolute;
            left: 0;
            width: 8000px;
        }

        .carousel ul li {
            float: left;
        }

        .carousel a {
            width: 100px;
            height: 100px;
            background-color: orange;
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -50px;
        }
        .carousel #leftbtn {
            left: 50px;
        }
        .carousel #rightbtn {
            right: 50px;
        }
    </style>
</head>

<body>
    <div class="carousel">
        <ul id="list">
            <li><img src="/images/spring.jpg" alt=""></li>
            <li><img src="/images/summer.jpg" alt=""></li>
            <li><img src="/images/autumn.jpg" alt=""></li>
            <li><img src="/images/winter.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" id="leftbtn"></a>
        <a href="javascript:;" id="rightbtn"></a>
    </div>
    <script>
        //得到ul 左右按钮
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');
        var oList = document.getElementById('list');
        //克隆第一个li放到ul的最后
        var cloneli = oList.firstElementChild.cloneNode(true);
        oList.appendChild(cloneli);

        //设置全局变量
        var idx = 0;  //代表第几张图片
        var lock = true;  //函数节流锁

        //右边按钮事件监听
        rightbtn.onclick = function () {
            if (!lock) return;
            lock = false;
            idx++;
            oList.style.left = idx * -1200 + 'px';
            oList.style.transition = 'left .5s ease 0s';
            setTimeout(function () {
                if (idx >= 4) {
                    oList.style.left = 0 + 'px';
                    idx = 0;
                    oList.style.transition = 'none';
                }
            }, 500);

            setTimeout(function () {
                lock = true;
            }, 500);
        };

        //左边按钮事件监听
        leftbtn.onclick = function () {
            if (!lock) return;
            lock = false;
           
            if (idx <= 0) {
                //让图片瞬间移动到最后一张克隆的图片上
                idx = 4;
                oList.style.left = idx * -1200 + 'px';
                oList.style.transition = 'none';
            }

            //小技巧:设置一个延时时间为0的延时器,虽然延时时间是0s,但可以让当过渡先瞬间取消,然后再加上
            setTimeout(function name(params) {
                idx--;
                oList.style.left = idx * -1200 + 'px';
                oList.style.transition = 'left .5s ease 0s'
            }, 0);

            setTimeout(function () {
                lock = true;
            }, 500);
        }
    </script>

</body>

</html>

⭐ 呼吸轮播图特效开发

实现下面效果的轮播图,点击左右两边的按钮,实现图片淡出、淡入切换:

20230425_16492520234251651153

**题目分析:**重点是点击按钮时,老图淡出、新图淡入,更改opacity属性就可以实现。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .carousel {
            width: 1202px;
            height: 800px;
            border: 1px solid #000;
            margin: 100px auto;
            position: relative;
        }

        .carousel ul {
            list-style: none;
        }
        .carousel ul li {
            /*图片透明度是0*/
            opacity: 0;
            position: absolute;
            top: 0;
            left: 0;
            transition: opacity 1s ease 0s;
        }

        .carousel ul li:first-child {
            /*第一张图片的透明度是1*/
            opacity: 1;
        }

        .carousel a {
            width: 100px;
            height: 100px;
            background-color: orange;
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -50px;
        }

        .carousel #leftbtn {
            left: 50px;
        }

        .carousel #rightbtn {
            right: 50px;
        }
    </style>
</head>

<body>
    <div class="carousel">
        <ul id="list">
            <li><img src="/images/spring.jpg" alt=""></li>
            <li><img src="/images/summer.jpg" alt=""></li>
            <li><img src="/images/autumn.jpg" alt=""></li>
            <li><img src="/images/winter.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" id="leftbtn"></a>
        <a href="javascript:;" id="rightbtn"></a>
    </div>
    <script>
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');
        var oList = document.getElementById('list');
        var lis = oList.getElementsByTagName('li');

        var idx = 0; //代表第几张图片
        var lock = true;  //函数节流锁

        //右边按钮事件监听
        rightbtn.onclick = function () {
            if (!lock) return;
            lock = false;

            //老图淡出
            lis[idx].style.opacity = 0;
            idx++;
            if (idx > 3) idx = 0;  //如果是最后一张图片了,则第一张图片是新图
            //新图淡入
            lis[idx].style.opacity = 1;

            setTimeout(function () {
                lock = true;
            }, 1000);
        };

        //左边按钮事件监听
        leftbtn.onclick = function () {
            if (!lock) return;
            lock = false;

            //老图淡出
            lis[idx].style.opacity = 0;
            idx--;
            if (idx < 0) idx = 3;  //如果是第一张图片,则最后最后一张是新图
            //新图淡入
            lis[idx].style.opacity = 1;

            setTimeout(function () {
                lock = true;
            }, 1000);
        };
    </script>
</body>

</html>

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

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

相关文章

JSP格式化标签 parseDate将指定时间格式字符串转为真正的date对象

格式化标签最后一个就是 parseDate 作用 将一个日期/时间格式字符串 转为 真正的date时间类型 有点无语 这种 东西应该都是在java中去做的 而不是在java中 这个建议也是做个了解即可 作用不是那么大 基本语法如下 这里 我们 直接编写代码如下 <% page contentType"…

智能优化算法应用:基于天牛须算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于天牛须算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于天牛须算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.天牛须算法4.实验参数设定5.算法结果6.参考文献7.…

2024年AMC8美国初中数学竞赛最后一个月复习指南(附资料)

还有一个半月的时间&#xff0c;2024年AMC8&#xff08;大家默认都直接叫这个比赛的英文名&#xff0c;而不叫中文名美国数学竞赛或美国初中数学竞赛了&#xff09;就要开始了。 有志于在2024年AMC8的比赛中拿到奖项的孩子已经在“磨拳霍霍”了。那么最后一个半月的时间该如何…

智能优化算法应用:基于热交换算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于热交换算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于热交换算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.热交换算法4.实验参数设定5.算法结果6.参考文献7.…

Java线程池的使用和最佳实践

第1章&#xff1a;引言 处理并发问题时&#xff0c;如果每次都新建线程&#xff0c;那系统的压力得有多大&#xff1f;这时候&#xff0c;线程池就像一个英雄一样出现了&#xff0c;它帮我们有效地管理线程&#xff0c;提高资源利用率&#xff0c;降低开销。那么&#xff0c;为…

还搞不懂什么是参数,超参数吗?三分钟快速了解参数与超参数的概念和区别!!!

文章目录 前言一、参数是什么&#xff1f;二、超参数是什么三&#xff0c;常使用的超参数有哪些 前言 参数是模型中可被学习和调整的参数&#xff0c;通过训练数据进行学习和优化&#xff1b; 而超参数则是手动设置的参数&#xff0c;用于控制模型的行为和性能&#xff0c;超…

探秘Python FastAPI、Sanic、Tornado 与Golang Gin性能之战!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python和Golang作为两种流行的编程语言&#xff0c;都拥有强大的异步框架&#xff0c;为开发者提供了在构建高性能应用时的选择。在Python阵营中&#xff0c;FastAPI、Sanic、Tornado等框架因其异步特性和高效的…

viple模拟器使用(四):unity模拟器中实现两距离局部最优迷宫算法

名字解读 两距离&#xff1a;指的是左侧距离和右侧距离 局部最优&#xff1a;对当前状态来说最好的选择&#xff0c;至于整体能不能达到最优&#xff0c;是无法确定的。 从节点1到节点5&#xff0c;一共有3条路 第1条路线&#xff1a;1→2→4→5&#xff0c;对应的花销是&…

LeetCode刷题---反转链表

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏&#xff1a;http://t.csdnimg.cn/ZxuNL http://t.csdnimg.cn/c9twt 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回溯算法&#xff0c;所以下面题目主要也是这些算法做的 我讲述…

Linux 基础认识

文章目录 前言Linux历史window历史Linux地位发行版本 前言 建议只看概述 Linux历史 概述&#xff1a; 由一个研究生受Minix操作系统启发编写的&#xff0c;因为功能实用&#xff0c;代码开源被世界人接收和开发 &#xff0c;最终正式发布 。 详情&#xff1a; 1991年10月5日…

JavaSE学习路线及经验所谈

前言 一.学习框架二.学习经验 相信很多小白刚开始学习Java时&#xff0c;都是靠自己在网上搜集资料&#xff0c;并没有明确规划&#xff0c;不知道要学习什么内容&#xff0c;也不知道学习的重点是什么&#xff0c;那么这篇文章会给你一个大致的指引&#xff0c;当然也可以作为…

Apache Doris 详细教程(二)

5、doris的查询语法 5.1、doris查询语法整体结构 SELECT [ALL | DISTINCT | DISTINCTROW ] -- 对查询字段的结果是否需要去重&#xff0c;还是全部保留等参数 select_expr [, select_expr ...] -- select的查询字段 [FROM table_references [PARTITION…

Project 1: The Game of Hog(CS61A)

&#xff08;第一阶段&#xff09;问题 5a&#xff08;3 分&#xff09; 实现该函数&#xff0c;该函数模拟了完整的 Hog 游戏。球员 交替轮流掷骰子&#xff0c;直到其中一名玩家达到分数。playgoal 您现在可以忽略 Feral Hogs 规则和论点; 您将在问题 5b 中实现它。feral_h…

微信小程序:调用 摄像头、选择照片或视频 都没反应 / wx.chooseImage 选择上传图片无反应

一、问题描述 微信小程序 调用 摄像头、选中的照片或视频&#xff0c;都没反应 wx.chooseImage 选择上传图片无反应 二、问题解决 2.1、设置 登录后台关联&#xff0c;点“设置” 2.2、服务内容声明 服务内容声明&#xff0c;用户隐私保护指引&#xff0c;更新 2.3、添加…

React立即更新DOM

正常情况下&#xff0c;react会等待set完毕后再进行页面渲染&#xff0c;所以在set时无法拿到更新后的dom import { useRef, useState } from "react"export default () > {const div useRef(null)const [count, setCount] useState(0)const btnClick () >…

手写实现一个动态代理框架

手写实现一个动态代理框架 什么是代理模式什么是动态代理动态代理中的编译、类加载与对象实例化手写实现一个动态代理框架实现细节DynamicProxyHandlerProxy生成代码写入代码到磁盘文件调用编译器进行编译调用类加载器进行类加载反射实例化删除前面生成的java文件和class文件 C…

LeetCode - 100. 相同的树 (C语言,二叉树,配图,简单)

利用分治思想&#xff0c;将大问题化解成为小问题&#xff0c;我们只需要比较&#xff1a; 1. 根节点的同时为空/不为空&#xff0c;不为空时值相等。 2. 左子树是否一样。 3. 右子树是否一样。 可以看出&#xff0c;这道题非常简单&#xff0c;但是为什么我们还要将它呢&#…

Linux 上的容器技术

容器实现封闭的环境主要要靠两种技术&#xff0c;一种是看起来是隔离的技术&#xff0c;称为 namespace&#xff08;命名空间&#xff09;。在每个 namespace 中的应用看到的&#xff0c;都是不同的 IP 地址、用户空间、进程 ID 等。另一种是用起来是隔离的技术&#xff0c;称为…

【系统运维】Centos部署Haproxy+Keepalived+RabbitMQ高可用集群

1.RabbitMQ高可用集群方案 &#xff08;1&#xff09;RabbitMQ搭建集群的作用&#xff1a;提高可用性、可靠性和处理能力&#xff0c;确保系统提供高效的消息传递服务 高可用性&#xff1a;通过集群&#xff0c;即使其中一个节点发生故障&#xff0c;其他节点仍然可以继续提供…

Elasticsearch:什么是向量数据库?

向量数据库定义 向量数据库是将信息存储为向量的数据库&#xff0c;向量是数据对象的数值表示&#xff0c;也称为向量嵌入。 它利用这些向量嵌入的强大功能来对非结构化数据和半结构化数据&#xff08;例如图像、文本或传感器数据&#xff09;的海量数据集进行索引和搜索。 向…