1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div class="colorblock1" id="b"></div>
  11. <button onclick="a()">变色</button>
  12. <style>
  13. .colorblock1 {
  14. width: 300px;
  15. height: 100px;
  16. margin: 20px auto;
  17. background-image: -webkit-linear-gradient(left, rgb(255, 0, 0), blue);
  18. /* Safari 5.1 - 6.0 */
  19. background-image: -o-linear-gradient(right, red, blue);
  20. /* Opera 11.1 - 12.0 */
  21. background-image: -moz-linear-gradient(right, red, blue);
  22. /* Firefox 3.6 - 15 */
  23. background-image: linear-gradient(to right, red, blue);
  24. /* 标准的语法(必须放在最后) */
  25. opacity: 1;
  26. }
  27. .colorblock2 {
  28. width: 300px;
  29. height: 100px;
  30. margin: 20px auto;
  31. background-image: -webkit-linear-gradient(left, rgba(228, 248, 50, 0.479), rgba(52, 235, 77, 0.932));
  32. /* Safari 5.1 - 6.0 */
  33. background-image: -o-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));
  34. /* Opera 11.1 - 12.0 */
  35. background-image: -moz-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));
  36. /* Firefox 3.6 - 15 */
  37. background-image: linear-gradient(to right, rgba(228, 248, 50, 0.438), rgba(52, 235, 77, 0.932));
  38. /* 标准的语法(必须放在最后) */
  39. opacity: 0;
  40. }
  41. </style>
  42. <script>
  43. //实现颜色渐弱然后渐强
  44. function a() {
  45. let d = document.getElementById('b')
  46. let j = 1
  47. let z = 0
  48. for (let i = 1; i >= 0; i = i - 0.001) {
  49. setTimeout(function () {
  50. d.style.cssText = `opacity: ${j}; `
  51. j = j - 0.001
  52. }, i * 300)
  53. }
  54. setTimeout(function () {
  55. d.setAttribute("class", "colorblock2")
  56. }, 400)
  57. for (let i = 2; i >= 1; i = i - 0.001) {
  58. setTimeout(function () {
  59. d.style.cssText = `opacity: ${z}; `
  60. z = z + 0.001
  61. }, i * 500)
  62. }
  63. }
  64. </script>
  65. </body>
  66. </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的数量级最好。
函数部分:

  1. function a() {
  2. let d = document.getElementById('b')
  3. let j = 1 //用于控制颜色消失时的透明度值
  4. let z = 0 //用于控制颜色出现时的透明度值
  5. for (let i = 1; i >= 0; i = i - 0.001) { //千万不要用循环体的i作为透明度变化的参数
  6. setTimeout(function () { //setTimeout直接加入宏任务队列
  7. d.style.cssText = `opacity: ${j}; `
  8. j = j - 0.001
  9. }, i * 300)
  10. }
  11. setTimeout(function () {
  12. d.setAttribute("class", "colorblock2")
  13. }, 400)
  14. //第二个for循环最好是第一个for循环的2倍,使得setTimeout的时间足够的长。
  15. for (let i = 2; i >= 1; i = i - 0.001) {
  16. setTimeout(function () {
  17. d.style.cssText = `opacity: ${z}; `
  18. z = z + 0.001
  19. }, i * 500)
  20. }
  21. }

注意一点,setTimeout的时间延迟都是从长到短的。

更多js动画效果:https://www.jb51.net/article/74686.htm
https://www.imooc.com/learn/167