缓动运动框架
每次的步长 = (总路程 - 当前位置) / 运动系数(6-10)
1function getStyle(el, attr) {
2 return el.currentStyle ? el.currentStyle[attr] : getComputedStyle(el)[attr]
3}
4
5function bufferMove(el, obj, fn) {
6 // fn就是回调函数
7 clearInterval(el.timer)
8
9 el.timer = setInterval(() => {
10 let flag = true // 判断是否所有属性都到达目标值,如果有一个属性没有到目标值,就将 flag 设置为 false。如果全部都到了目标值,那么 flag 就不会被改变为 false,就是初始 true
11 for (const attr in obj) {
12 // 判断 attr 是不是 opacity,是:采用一种获取办法,不是:采用之前的获取方法
13 if (attr == 'opacity')
14 var cur = Math.round(getStyle(el, attr) * 100)
15 else
16 var cur = Number.parseInt(getStyle(el, attr))
17
18 let step = (obj[attr] - cur) / 10
19 step = step > 0 ? Math.ceil(step) : Math.floor(step)
20
21 // if(cur == obj[attr]){
22 // clearInterval(el.timer);
23 // }
24
25 if (cur != obj[attr]) {
26 // 如果有一个当前值,不等于目标值,说明没有全部执行完成
27 flag = false
28 }
29
30 // 赋值时也分两种情况,一种是透明度,另一种是带有单位 px 的
31 if (attr == 'opacity') {
32 el.style.opacity = (cur + step) / 100
33 el.style.filter = `alpha(opacity=${cur + step})`
34 }
35 else {
36 el.style[attr] = `${cur + step}px`
37 }
38 }
39
40 if (flag) {
41 // 如果 flag 为假,说明没有全部属性达到目标值,那么不清除定时器,如果 flag 为 true 说明全部属性都达到了目标值,就清除定时器
42 clearInterval(el.timer)
43
44 // fn && fn();
45 // 回调函数的 this 指向 window,当该运动框架适用于元素集合时,this 执行导致报错
46
47 // if(fn) fn();
48 // 改 call 就是修改函数的调用时的 this 指向
49 if (fn)
50 fn.call(el)
51 }
52 }, 20)
53}