纯JS实现翻页动画效果

3,321 阅读2分钟

大家好,我是隐冬,今天用原生js给大家写一个翻页的效果。

首先完成页面的静态布局。

屏幕快照 2021-07-01 15.17.13.png

html里面很简单,只有一个ul标签和一个button按钮。ul中的li是通过js动态生成的。

<body>
	<ul id="ul"></ul>
	<button>切换</button>
</body>

js先获取页面中的ul元素和button。然后创建一个arr数组,用于存储每个li元素的位置信息。

window.onload = function () {
    const oUl = document.getElementById('ul');
    const button = document.querySelector('button');
    // 存储运动元素位置信息
    let arr = [];
}

创建一个start函数来开始编写动画,首先调用一个start,在将start绑定到button的事件中。

start();
button.onclick = start;

函数中首先进行li的生成,判断一下如果没有ul内容为空,则表示没有li使用for循环生成。生成之后再将每个li的位置信息存放到数组中,最后再用绝对定位改造一下。有了绝对定位li就可以做动画了。

const aLi = oUl.getElementsByTagName('li');
const num = 10;
// 参与运动的元素个数,下标从0开始
let iNow = num - 1;
// 如果没有li
if (!oUl.innerHTML) {
    // 创建num个li放在ul里面
    for (let i = 0; i < num; i++) {
        let oLi = document.createElement('li');
        oUl.appendChild(oLi);
    }
    // 将每个li的位置存储在arr中
    for (let i = 0; i < aLi.length; i++) {
        arr.push([aLi[i].offsetLeft, aLi[i].offsetTop]);
    }
    // 循环为每个li添加定位,使用定位固定位置
    for (let i = 0; i < aLi.length; i++) {
        aLi[i].style.position = 'absolute';
        aLi[i].style.left = arr[i][0] + 'px';
        aLi[i].style.top = arr[i][1] + 'px';
        aLi[i].style.margin = 0;
    }
}

如果li存在则使用动画删除当前的li,再创建一批新的li。

首先设置一个定时器,每隔100ms执行一次,这样每个li就会相隔100ms开始运动。运动使用之前定义好的move运动函数,这个再前几篇文章中有封装的,这里就不多说了。最后将iNow减1,iNow是当前运动到的元素。

当iNow等于0的时候表示所有的元素都运动完了,清除这个定时器。然后再开一个定时器执行一次运行。

第一次的运动是移除,第二次的运动是移入。

if (!oUl.innerHTML) {
    ...
} else {
    // 如果存在li则运动
    let timer = setInterval(function () {
        // 调用move函数
        move(aLi[iNow], { left: 200, top: 250, opacity: 0 });
        // iNow 是运动的li,每隔100毫秒运动一个,当为0时运动完成,清除定时器
        if (iNow == 0) {
            clearInterval(timer);
            // 重置iNow
            iNow = num - 1;
            let timer2 = setInterval(function () {
                // 复原li
                move(aLi[iNow], { left: arr[iNow][0], top: arr[iNow][1], opacity: 100 });
                // 复原完成
                if (iNow == 0) {
                    clearInterval(timer2);
                    iNow = num - 1;
                } else {
                    iNow--;
                }
            }, 100);
        } else {
            iNow--;
        }
    }, 100);
}

写完的效果就是这个样子的。

未命名.gif

源码自取地址: 自取链接: github.com/xiaoyindong…