DOM 之在動畫結束後做某件事

這下有趣囉。

簡述

簡單來說要實作出跟 jQuery animate 的 callback 一樣的效果。

所以上網查了一下,發現邏輯不複雜,只需要透過 setTimeout 來讓 callback 等到動畫結束時才執行。

在動畫結束後刪除元素

舉一個簡單的範例,要做出這樣的效果:

animation-01

1
2
3
4
<div class="wrapper">
<div class="block"></div>
</div>
<button>Animation trigger</button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 動畫秒數
let duration = 1
// 點按鈕 -> 執行動畫
document.querySelector('button')
.addEventListener('click', handlerAnimation)

function handlerAnimation () {
// 取得元素
const element = document.querySelector('.block')
// 利用 transition 做出漸變效果
element.style.transform = 'translateX(400px)'
element.style.transition = `transform ${duration}s`
// 等動畫結束後才把 .block 移除
setTimeout(() => {
element.remove()
}, duration * 1000)
}

就這麼簡單,不用懷疑!

捏一個陽春版的 animate

其實就是用 function 包裝起來,然後添加一些可調整的參數:

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
/*
@param selector: 要執行動畫的元素
@param cssRule: 要調整的 css 規則
@param duration: 動畫秒數
@param callback: 動畫結束後要做的事
*/
function animate(selector, cssRule, duration, callback) {
const element = document.querySelector(selector)
for (let key in cssRule) {
// 更新 css 規則
element.style[key] = cssRule[key]
// 漸變效果
element.style['transition'] = `${key} ${duration}s`
}
// 動畫執行完後要做的事
setTimeout(() => {
// 記得把指定元素用 callback 帶回去
callback(element)
}, duration * 1000)
}

// 按下按鈕 -> 執行動畫 -> 動畫結束後刪除元素
document
.querySelector('button')
.addEventListener('click', () => {
animate(
'.block',
{'transform': 'translateX(400px)'},
1,
(element) => element.remove()
)
})

如果要支援多個 css 規則要修改一下 transition 的部分:

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
/*
@param selector: 要執行動畫的元素
@param cssRule: 要調整的 css 規則
@param duration: 動畫秒數
@param callback: 動畫結束後要做的事
*/
function animate(selector, cssRule, duration, callback) {
const element = document.querySelector(selector)
// 儲存要加上漸變效果的規則
let transitionValue = []
// 更新 css 規則
for (let key in cssRule) {
element.style[key] = cssRule[key]
// 儲存所有 css 規則
transitionValue.push(key)
}
/*
設定漸變,先 join 完再補上尾綴
重複的規則:'秒數s, ' => aaa 1s, bbb 1s
*/
element.style['transition'] = transitionValue.join(` ${duration}s, `) + ` ${duration}s`
// 動畫執行完後要做的事
setTimeout(() => {
callback(element)
}, duration * 1000)
}

document
.querySelector('button')
.addEventListener('click', () => {
animate(
'.block',
{
'transform': 'translateX(400px)',
'background-color': 'red',
'width': '0px'
},
1,
(element) => element.remove()
)
})

因為 transition 的部分沒辦法用 += 來新增值,所以要拆開來寫,不能寫在迴圈裡面。

animation-02

善用跳脫字元,避免不合法的輸入內容 mentor-program-day42
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×