这是一段点击按钮后就会导致整个列表倒过来排列的代码
加上过渡动画会更好看,但因为它改变了DOM结构,所以没法使用CSS动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> #btn { margin-bottom: 20px; }
#list { list-style: none; padding: 20px; margin: 0; border: 1px solid #ccc; width: 300px; height: 300px; display: flex; flex-direction: column; justify-content: space-around; align-items: center; }
#list li { width: 100%; height: 30px; font-size: 20px; line-height: 30px; border-radius: 20px; text-align: center; background-color: #bfa; } </style>
<body> <button id="btn">倒转</button> <ul id="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> </ul> <script> const list = document.querySelector('#list') const btn = document.querySelector('#btn')
btn.addEventListener('click', () => { const len = list.children.length let index = 0 while (index < len - 1) { const node = list.children[index] const insert = list.children[len - 1] list.insertBefore(insert, node) index++ } }) </script> </body> </html>
|
其实Flip方案可以解决对元素结构变化应用动画的问题,它分为四个过程:
F:first,记录起始位置(x、y坐标)
![](/img/loading.gif)
L:last,记录结束位置(也是x、y坐标)
![](/img/loading.gif)
I:invert,反转元素到起始位置(计算偏移量,起始位置-结束位置)
- 运行到这一步时,由于JS未执行完毕,浏览器尚未渲染结束位置,所以浏览器页面仍呈现的是起始位置
- 此时立即将为偏移的元素设置CSS translate为偏移量,结果是JS结束执行后元素结构已经改变了,但看起来似乎没有变化
- 偏移量为0的元素不应用动画
![](/img/loading.gif)
P:play,播放动画回到结束位置(去除偏移和CSS属性)
![](/img/loading.gif)
Vue的Transition就是使用Flip方案实现的