<!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></head><body><div class="colorblock1" id="b"></div><button onclick="a()">变色</button><style>.colorblock1 {width: 300px;height: 100px;margin: 20px auto;background-image: -webkit-linear-gradient(left, rgb(255, 0, 0), blue);/* Safari 5.1 - 6.0 */background-image: -o-linear-gradient(right, red, blue);/* Opera 11.1 - 12.0 */background-image: -moz-linear-gradient(right, red, blue);/* Firefox 3.6 - 15 */background-image: linear-gradient(to right, red, blue);/* 标准的语法(必须放在最后) */opacity: 1;}.colorblock2 {width: 300px;height: 100px;margin: 20px auto;background-image: -webkit-linear-gradient(left, rgba(228, 248, 50, 0.479), rgba(52, 235, 77, 0.932));/* Safari 5.1 - 6.0 */background-image: -o-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));/* Opera 11.1 - 12.0 */background-image: -moz-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));/* Firefox 3.6 - 15 */background-image: linear-gradient(to right, rgba(228, 248, 50, 0.438), rgba(52, 235, 77, 0.932));/* 标准的语法(必须放在最后) */opacity: 0;}</style><script>//实现颜色渐弱然后渐强function a() {let d = document.getElementById('b')let j = 1let z = 0for (let i = 1; i >= 0; i = i - 0.001) {setTimeout(function () {d.style.cssText = `opacity: ${j}; `j = j - 0.001}, i * 300)}setTimeout(function () {d.setAttribute("class", "colorblock2")}, 400)for (let i = 2; i >= 1; i = i - 0.001) {setTimeout(function () {d.style.cssText = `opacity: ${z}; `z = z + 0.001}, i * 500)}}</script></body></html>
原理:通过 JS 函数修改颜色的透明度属性,从1到0逐渐减少透明度就会让颜色消失,再从0到1逐渐增加透明度就可以让颜色重新出现,如果在消失和出现之间在变换样式颜色,就可以实现颜色从一个颜色逐渐变为另一个颜色。
方法L:利用for循环,和三个 setTimeout安排渐变和颜色改变的顺序,三个setTimeout的延迟经过测试,可以是 400,500,600或者他们的倍数。并且要做出渐进的动画效果,每个setTimeout的延迟还不能相同,必须是成一个函数递增的关系,所以就可以在延迟上乘上一个步长 ,让时间延迟成 y = x * 步长 的一次函数关系,这样每个渐变之间相差相同的时间,就可以实现顺滑的渐变效果了。
不能用循环体的变量 i 作为透明度的参数
并且注意,for循环在执行时遇到setTimeout会直接把它放到宏任务队列,并不会执行setTimeout中的回调函数,只有当宏任务开始执行时才回调,所以函数中设置透明度的选项只会等for循环执行完后才会执行,此时 for上的 i 早就已经变成最大/最小值了,所以千万不能用循环体的变量 i 来作为透明度的参数,有些人图省事直接用 i 作为变量,最后发现根本没有渐变的效果。
所以需要在循环体外单独创建两个变量,来指定透明度的变化。
透明度的递增递减的步长最好在0.001的数量级最好。
函数部分:
function a() {let d = document.getElementById('b')let j = 1 //用于控制颜色消失时的透明度值let z = 0 //用于控制颜色出现时的透明度值for (let i = 1; i >= 0; i = i - 0.001) { //千万不要用循环体的i作为透明度变化的参数setTimeout(function () { //setTimeout直接加入宏任务队列d.style.cssText = `opacity: ${j}; `j = j - 0.001}, i * 300)}setTimeout(function () {d.setAttribute("class", "colorblock2")}, 400)//第二个for循环最好是第一个for循环的2倍,使得setTimeout的时间足够的长。for (let i = 2; i >= 1; i = i - 0.001) {setTimeout(function () {d.style.cssText = `opacity: ${z}; `z = z + 0.001}, i * 500)}}
注意一点,setTimeout的时间延迟都是从长到短的。
更多js动画效果:https://www.jb51.net/article/74686.htm
https://www.imooc.com/learn/167
