animationend 事件在 CSS 动画完成后触发。

CSS 动画播放时,会发生以下三个事件:

  1. animationstart - CSS 动画开始后触发
  2. animationiteration - CSS 动画重复播放时触发
  3. animationend - CSS 动画完成后触发

在这三个事件函数中,均可以使用 event.animationName 属性,判断是在执行哪个动画。

个人觉得 animationend 事件用的多一点。

案例1:标签的隐现

<button type="button" id="btn">点击</button>
<div class="box" id="box"></div>
.box{width: 100px;height: 100px;background: #f00;display: none;margin-left: auto;margin-right: auto;
}
.box.show{display: block;
}
@keyframes showAni {0%{opacity: 0;}100%{opacity: 1;}
}
@keyframes hideAni {0%{opacity: 1;}100%{opacity: 0;}
}
  • 默认 div.box 是隐藏的。
  • 点击按钮,让 div.box 显示;但是动画效果全部由 CSS 的 keyframes 去完成。
  • 显示的动画很简单,让 div.box 显示的同时,执行 animation 动画就行。显示利用了 类 show 去执行,好处是可以判断 div.box 是执行显示效果,还是执行隐藏效果。
  • 但是隐藏的时候,要先执行动画,当动画完毕的时候,再利用 animationend 事件函数,让 div.box 隐藏。
let btn = document.getElementById("btn");
let box = document.getElementById("box");
btn.addEventListener("click",function(){if( !box.classList.contains("show") ){ // 如果 box 不包含 类show,说明需要显示它。box.classList.add("show");box.style.animation = "showAni  0.5s  both";}else{   // 否则就要隐藏box.style.animation = "hideAni  0.5s  both";}
});
// 隐藏动画完毕时,就要去掉 show 的类。
box.addEventListener("animationend",function(event){if(event.animationName === "hideAni" ){box.classList.remove("show");}
});

案例2:多个标签的隐现

<div style="text-align:center;">多个标签的动画显示和隐藏<button type="button" id="btn">点击</button>
</div>
<div class="box" id="box"><ul><li>1</li><li>2</li><li>3</li></ul>
</div>
*{margin: 0;padding: 0;
}
ul,li,ol{list-style-type: none;
}.box{width: 100px;height: 100px;display: none;perspective: 500px;margin-left: auto;margin-right: auto;
}
.box li{background: #f00;
}
.box.show{display: block;
}
@keyframes showAni {0%{opacity: 0;transform: rotateY(90deg);}100%{opacity: 1;transform: rotateY(0deg);}
}
@keyframes hideAni {0%{opacity: 1;transform: rotateY(0deg);}100%{opacity: 0;transform: rotateY(90deg);}
}

整体思路,跟前面的很类似。

不过,这次的动画是直接写在 每个 li 上面,而不是 div.box 整体。因此,显示的时候,要对 li 遍历,依次开展动画;隐藏的时候,也是同理。

在多个标签隐藏时候,要用到 setTimeout,等待所有动画执行完毕后,才去掉 div.box 的类 show。

let btn = document.getElementById("btn");
let box = document.getElementById("box");
btn.addEventListener("click",function(){let li = box.querySelectorAll("li");  // 获取所有的 li 标签if( !box.classList.contains("show") ){box.classList.add("show");li.forEach(function(value, key, parent){value.style.animation =`showAni 0.2s ${0.2*key}s both`;});}else{// for(let i=li.length-1; i>=0 ; i--){//     li[i].style.animation =`hideAni 0.2s ${0.2*(li.length-1-i)}s both`;// }li.forEach(function(value, key, parent){value.style.animation =`hideAni 0.2s ${0.2*(li.length-1-key)}s both`;});setTimeout(function(){box.classList.remove("show");},200*(li.length-1));  // 等待所有动画执行完毕,去掉 box 的show类。}
});

案例3:图片轮播

这个效果应该被写滥了。。。。几乎是一个学 JS 的人必会。

不过,这次我结合 animationend 事件写一个,带有渐隐效果的轮播。以前都是用 jQuery,今天换个思路。

HTML 代码如下:

<div class="picShow"><ul class="picUl" id="picUl"><li><a href="#"><img src="../images/pic1.jpg" alt=""></a></li><li><a href="#"><img src="../images/pic2.jpg" alt=""></a></li><li><a href="#"><img src="../images/pic3.jpg" alt=""></a></li><li><a href="#"><img src="../images/pic4.jpg" alt=""></a></li><li><a href="#"><img src="../images/pic5.jpg" alt=""></a></li></ul><div class="picDots" id="picDots"></div>
</div>
  • 轮播的控制点利用 DOM,根据图片的个数( li 的个数)动态生成;
  • 默认图片是隐藏的,display:none;
  • li 的显示和隐藏是这个案例的关键,因此,把标签的隐藏和显示分别封装成了 函数。其中,为了过渡隐藏动画,利用了 animationend 事件。当隐藏动画完毕后,让标签 display:none;

CSS代码如下:

*{margin: 0;padding: 0;
}
img{border:none;
}
ul,li,ol{list-style: none;
}
.picShow{position: relative;margin-left: auto;margin-right: auto;
}
.picShow,
.picUl>li,
.picUl>li>a{width: 600px;height: 399px;overflow: hidden;
}
.picUl>li>a{display: block;
}
.picUl>li{position: absolute;top:0;left:0;display: none;
}
.picUl>li.show{display: block;
}
.picDots {position: absolute;right:20px;bottom:20px;
}
.picDots span{display: inline-block;width: 16px;height: 16px;background: #fff;margin-left: 10px;cursor: pointer;
}
.picDots span.on{background: #f30;
}
@keyframes showAni {0%{opacity: 0;}100%{opacity: 1;}
}
@keyframes hideAni {0%{opacity: 1;}100%{opacity: 0;}
}

JavaScript 代码如下:

let li = document.querySelectorAll("#picUl>li");
let dots = document.getElementById("picDots");
let span = [];
function  init(){for(let i=0; i<=li.length-1 ; i++ ){// 动态生成轮播的控制点let newSpan = document.createElement("span");dots.appendChild(newSpan);span.push(newSpan);if( i===0 ){newSpan.className = "on";}// 给每个 li 添加 animationend 事件li[i].addEventListener("animationend",function(event){if( event.animationName === "hideAni"){this.classList.remove("show");}});}showTag(li[0]);
}
// 显示某个标签
function showTag(tag){tag.classList.add("show");tag.style.animation = `showAni 0.5s both`;
}
// 隐藏某个标签
function hideTag(tag){tag.style.animation = `hideAni 0.5s both`;
}
init(); // 初始化函数
// 给 span 添加事件
for(let i=0 ; i<= span.length-1; i++){span[i].addEventListener("click",function(){this.classList.add("on");showTag(li[i]);// 其余的点去掉 on,其余的 li 隐藏。for(let j=0 ; j<=span.length-1 ; j++ ){if( j!==i){span[j].classList.remove("on");hideTag(li[j]);}}});
}

案例4:带退出动画的轮播

具体效果可以参考网游逆水寒的官网。

在人物轮播中,旧的内容动画退出后,才出现新的人物。

借用前面的思路,我也来做一个简单的带退出动画的轮播。

样式写的简陋,但是思路很重要。

HTML结构:

<div class="box"><ul class="picUl" id="picUl"><li><img src="../images/1.jpg" alt=""><h1>图片1</h1></li><li><img src="../images/2.jpg" alt=""><h1>图片2</h1></li><li><img src="../images/3.jpg" alt=""><h1>图片3</h1></li></ul><div class="dots" id="dots"></div>
</div>

CSS:要在CSS 里写出每个部分的进入、退出动画。

*{margin: 0;padding: 0;
}
ul,li,ol{list-style: none;
}
img{border:none;
}
.picUl img{width: 200px;
}
.box{background: #ff0;margin-left: auto;margin-right: auto;position: relative;overflow: hidden;
}
.box,
.picUl>li{width: 400px;height: 200px;overflow: hidden;
}
.picUl>li  img{position: absolute;left:0;top:30px;
}
.picUl>li  h1{position: absolute;right:0;top:30px;
}
.picUl>li{display: none;
}
.picUl .show{display: block;
}
@keyframes leftIn {0%{opacity: 0;transform: translateX(-100px);}100%{opacity: 1;transform: translateX(0);}
}
@keyframes leftOut {0%{opacity: 1;transform: translateX(0);}100%{opacity: 0;transform: translateX(-100px);}
}
@keyframes rightIn {0%{opacity: 0;transform: translateX(100px);}100%{opacity: 1;transform: translateX(0);}
}
@keyframes rightOut {0%{opacity: 1;transform: translateX(0);}100%{opacity: 0;transform: translateX(100px);}
}
.dots{position: absolute;left:0;right:0;bottom:10px;text-align: center;
}
.dots span{display: inline-block;width: 16px;height: 16px;background: #fff;margin-left: 5px;margin-right: 5px;cursor: pointer;
}
.dots span.on{background: #f00;
}

JavaScript:

let dots = document.getElementById("dots");
let li = document.querySelectorAll("#picUl>li");
let img = document.querySelectorAll("#picUl img");
let nowIndex = 0;
let nextIndex = 0 ;
let dotSpan = [];
function init(){for(let i=0 ; i<=li.length-1 ; i++){let newSpan = document.createElement("span");dots.appendChild(newSpan);dotSpan.push( newSpan );if( i === 0 ){newSpan.classList.add("on");}}showTag( li[0] );
}
function showTag(tag){tag.classList.add("show");tag.children[0].style.animation = "leftIn 0.3s both";tag.children[1].style.animation = "rightIn 0.3s both";
}
function hideTag(tag){tag.children[0].style.animation = "leftOut 0.3s both";tag.children[1].style.animation = "rightOut 0.3s both";
}
init();  // 初始化init// 给图片添加动画事件。当图片动画结束后,让 li 隐藏
// 给控制点添加事件
for(let i=0 ; i <= li.length-1 ; i++ ){img[i].addEventListener("animationend",function(event){if( event.animationName === "leftOut" ){this.parentNode.classList.remove("show");}});dotSpan[i].addEventListener("click",function(){this.classList.add("on");for( let j=0 ; j <= li.length-1 ; j++ ){if( j !== i ){dotSpan[j].classList.remove("on");hideTag( li[j] )}}// 待退出后,再执行进入动画;// 不写 setTimeout ,直接 运行 showTag// 则是退出和进入同时进行setTimeout(function(){showTag( li[i] );},300);});
}

瞬间觉得轮播太有意思了~~

JavaScript 练手小技巧:animationend 事件及其应用小案例相关推荐

  1. JavaScript 练手小技巧:打字小游戏

    放假闲来无事,一群小屁孩想玩我的电脑. 字都不会打,还玩电脑. 用 js 写一个打字游戏,打不到 100 分,就不要玩我的电脑~~~!!! 整体界面如下所示,一切从简~ HTML 结构 <div ...

  2. c语言倒计时不影响进程_初学C语言没有项目练手怎么行,这17个小项目收下不谢...

    image C语言是我们大多数人的编程入门语言,对其也再熟悉不过了,不过很多初学者在学习的过程中难免会出现迷茫,比如:不知道C语言可以开发哪些项目,可以应用在哪些实际的开发中--,这些迷茫也导致了我们 ...

  3. 练手的70个超火python小项目,小编建议收藏哦,送你们玩

    相信正在学Python你一定为了没有练手项目而发愁,小编精心准备出了70个Python的练手项目,相信能够喂饱大伙儿吧!哈哈! 这里面的项目都很有代表性,不只是可以用来练手,而且在以后的工作中都有很实 ...

  4. 记一次练手的项目经历-事件管理系统

    此项目既为练手,也为简化个人工作.回过头来看,其实前端耗费的时间比较久,其实可以用elementadmin这个成熟框架的. 项目主要技术点: 动态数据源,数据库动态添加,添加后动态切换查询数据 自定义 ...

  5. H5练手项目-写一个菜鸟裹裹小程序

    新手写小程序并不简单,菜鸟裹裹查看快递是很方便的,平常自己查看快递的时候都是在用.当我在微信端搜索菜鸟裹裹小程序时,却没有发现,于是便想自己动手仿app版写一个菜鸟裹裹的小程序,对其中的快递查询物流跟 ...

  6. 超值的收藏得Python 100个小技巧,入门学习必备小知识

    前言 大家早好.午好.晚好吖 ❤ ~ 我给大家准备了一些资料,包括: 2022最新Python视频教程.Python电子书10个G (涵盖基础.爬虫.数据分析.web开发.机器学习.人工智能.面试题) ...

  7. JavaScript 练手小技巧:页面高亮操作提示和蒙板

    在页面上,有时候会遇到操作提示,如下图所示. 可以很直观的告诉用户,关键的操作在哪里,有什么做作用. 需要说明的是,被高亮的部分,并不是目标的真实标签,而是用的其他标签模拟的. 真实的标签被 mask ...

  8. JavaScript 练手小技巧:#RRGGBB 和 rgb(255,255,255)颜色代码相互转换

    看到有人在 CSDN 上写颜色的转换代码,突发奇想,用 JavaScript 也写一个. 一.相关知识点 (1)常用颜色代码方式,有两种 #RRGGBB 和 rgb(255,255,255) 用 #R ...

  9. JavaScript 练手小技巧:我用canvas画出了王者荣耀英雄属性的雷达图

    新年伊始,学习不止. 顺带恭喜下自己博客点击量突破 20w~啦~~ 不容易啊~~ ----------------------------------------------------------- ...

最新文章

  1. 为什么说Transformer就是图神经网络?
  2. 《Mysql数据库及应用》_MySQL数据库及应用
  3. 【Flutter】Animation 动画 ( Flutter 动画基本流程 | 创建动画控制器 | 创建动画 | 设置值监听器 | 设置状态监听器 | 布局中使用动画值 | 动画运行 )
  4. 《Java 核心技术卷1 第10版》学习笔记------ 控制可见性的4个访问修饰符详解
  5. linux上安装fio教程,fio工具安装及使用
  6. python全栈和java全栈_Python是全栈式开发语言吗?原因竟是这样!
  7. Scikit-learn:最近邻搜索sklearn.neighbors
  8. 浙江工业大学计算机学院的博士招生,浙江工业大学计算机科学与技术学院、软件学院...
  9. Python3爬虫与多线程
  10. Xilinx FPGA配置clocking时钟动态相位输出
  11. MSP430指令初探
  12. 上传照片(身份证照片正反面)
  13. PyTorch Python API:FX || Intro
  14. iOSUILable边距设置
  15. php生成小程序二维码出现40001的情况
  16. 愚人节的一天(快乐+2)
  17. 更新数据update
  18. Understand安装与使用
  19. 微信订阅号之连接服务器
  20. 最新PHP/SG11扩展解密视频教程分享

热门文章

  1. Java|static关键字【实例变量与类变量、实例方法与类方法】
  2. Python面向对象编程(上)
  3. C++学习1:C++友元函数和友元类
  4. 机器学习-什么是机器学习、监督学习和无监督学习
  5. 山西最新建筑施工八大员之安全员模拟题集及答案解析
  6. mysql枫_MySQL_java语言存取mysql快速构建,By 风过留枫, 出处:dujid 环境 - phpStudy
  7. [Android]ButterKnife-无尽之刃-绑定视图控件和事件的快速开发工具
  8. 苹果发布会前总被剧透?这家公司为防移动数据泄露这样做
  9. 权利的游戏-第七季第七集
  10. IDEA 学生无需破解免费申请(可用学生证和教育邮箱申请)