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

  • 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费如需要项目实战或者是体系化资源,文末名片加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.mfbz.cn/a/214268.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SDN之Ubuntn20.04OpenDaylight控制器的安装

目录 1.OpenDaylight简介2.安装JAVA环境3.安装OpenDaylight4.问题总结 1.OpenDaylight简介 OpenDaylight&#xff08;ODL&#xff09;是一个开源的软件定义网络&#xff08;SDN&#xff09;控制器平台&#xff0c;提供了非常美观且功能完善的可视化管理界面&#xff0c;方便用…

《YOLOv7原创自研》专栏介绍 CSDN独家改进创新实战专栏目录

YOLOv7原创自研 https://blog.csdn.net/m0_63774211/category_12511937.html &#x1f4a1;&#x1f4a1;&#x1f4a1;全网独家首发创新&#xff08;原创&#xff09;&#xff0c;适合paper &#xff01;&#xff01;&#xff01; &#x1f4a1;&#x1f4a1;&#x1f4a1;…

Docker下安装可视化工具Portainer

目录 Portainer简介 Portainer安装 Portainer简介 Portainer是一款开源的容器管理平台&#xff0c;它提供了一个易于使用的Web UI界面&#xff0c;可用于管理和监控容器和集群&#xff0c;旨在使容器管理更加简单和可视化&#xff0c;适用于各种规模的容器环境&#xff0c;从…

淘宝店铺所有商品数据接口(淘宝 API 接口)

要获取淘宝店铺所有商品数据&#xff0c;您可以使用淘宝开放平台提供的 API 接口。具体步骤如下&#xff1a; 在淘宝开放平台注册并登录&#xff0c;创建一个应用&#xff0c;获取到所需的 App Key 和 App Secret 等信息。 使用获取到的 App Key 和 App Secret 进行签名和认证…

【C++ Primer Plus学习记录】嵌套循环和二维数组

目录 1.初始化二维数组 2.使用二维数组 for循环是一种处理数组的工具。下面进一步讨论如何使用嵌套for循环中来处理二维数组。 C没有提供二维数组类型&#xff0c;但是用户可以创建每个元素本身都是数组的数组。例如&#xff0c;假设要存储5个城市在4年间的最高温度&#xff…

IPv6是趋势!如何在Windows上禁用或启用IPv6?有3种简单的方法

IPv6是IPv4的一个更加安全、可扩展和可靠的继任者。然而&#xff0c;这种较新的互联网协议与IPv4不向后兼容&#xff0c;并且大多数VPN服务提供商不支持IPv6协议。 Microsoft不建议用户禁用IPv6或其组件&#xff0c;除非他们需要解决网络问题。但是&#xff0c;如果你计划禁用…

android studio安装SDK时无法勾选

这两天帮助学妹安装android studio安装SDK时无法勾选&#xff0c;记录一下最终解决办法。头大。 核心 360 问题 网上所有方法都尝试了包括挂梯子&#xff0c;改hosts&#xff0c;盘符权限等等。 最终解决下载360 使用这两个&#xff0c;DNS注意要用8.8.8.8的 成功解决

DLL缺失

DLL缺失 参考链接&#xff1a; 方法五&#xff0c;亲测有用

栈和队列的OJ题——14.用栈实现队列

14.用栈实现队列 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 此题可以用两个栈实现&#xff0c;一个栈进行入队操作&#xff0c;另一个栈进行出队操作 出队操作&#xff1a; 当出队的栈不为空是&#xff0c;直接进行出栈操作&#xff…

【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标☆

【字符串匹配】【KMP算法】Leetcode 28 找出字符串中第一个匹配项的下标 &#xff08;1&#xff09;前缀和后缀&#xff08;2&#xff09;前缀表&#xff08;最长相同的前缀和后缀的长度&#xff09;&#xff08;3&#xff09;匹配过程示意&#xff08;4&#xff09;next数组的…

计算机导论——第39章 文件和目录

除了虚拟化CPU和内存&#xff0c;另外一个是持久存储&#xff0c;永久存储信息。持久存储设备与内存不同&#xff0c;内存在断电时内容会丢失&#xff0c;而持久存储设备会保持这些数据不变。 1. 文件和目录 文件就是一个线性字节数组&#xff0c;每个字节都可以读取或者写入…

面试题:说说 Cookie、Session、Token、JWT?

文章目录 什么是认证&#xff08;Authentication&#xff09;什么是授权&#xff08;Authorization&#xff09;什么是凭证&#xff08;Credentials&#xff09;什么是 Cookiecookie 重要的属性 什么是 Sessionsession 认证流程 Cookie 和 Session 的区别什么是 Token&#xff…

Python面向对象④:继承【侯小啾python领航班系列(二十二)】

Python面向对象④:继承【侯小啾python领航班系列(二十二)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…

loguru的简单使用

详细使用&#xff1a;Table of contents — loguru documentation 【1】日志的级别 日志级别默认分为6种 1、NOTSET (0)2、DEBUG (1)3、INFO (2)4、WARNING (3)5、ERROR (4)6、CRITICAL (5) logging 执行时输出大于等于设置的日志级别的日志信息&#xff0c;如设置日…

leetCode 51.皇后 + 回溯算法 + 图解 + 笔记

按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。每一种解法包…

nodejs介绍

nodejs官网支持的各种库api https://nodejs.org/docs/latest-v21.x/api/http.html nodejs包括vp8引擎和内置的基本库如fs,path,http,querystring等&#xff0c;也可以用npm按转第三方库 npm是nodejs环境的包管理工具&#xff0c;可以为这个环境安装卸载各种包。 npm install pk…

类和对象——(4)特殊的成员函数

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 一个人不是在逆境中成长&#xff0c;就…

4/150:寻找两个正序数组的中位数⭐ 5/150最长回文子串

题目&#xff1a;4/150寻找两个正序数组的中位数 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 题解1&#xff1a;暴力 暴力思路简介&#x…

JAVA毕业设计113—基于Java+Springboot+Vue的体育馆预约系统(源代码+数据库+12000字论文)

基于JavaSpringbootVue的体育馆预约系统(源代码数据库12000字论文)113 一、系统介绍 本项目前后端分离&#xff0c;本系统分为管理员、用户两种角色 用户角色包含以下功能&#xff1a; 注册、登录、场地(查看/预订/收藏/退订)、在线论坛、公告查看、我的预订管理、我的收藏…

综合实验—增强分析和配置中小型企业网络的综合能力

实验拓扑、实验编址如下图表所示&#xff0c;本实验模拟了一个企业网络场景&#xff0c; 其中R1和R2为公司总部路由器&#xff0c;交换机S1、S2、S3组成了总部的园区网&#xff0c;R3、R4、 R5为公司分部的路由器。 总部园区网中3台交换机都运行MSTP协议&#xff0c;用来防止二…
最新文章