1 需求
效果就是下面这样,就是一次滚出一个元素,无限循环,可以使用死数据,也可以追加,当然具体动画你可以修改代码。

思路
- 使用
css
做过渡动画,用js控制滚动(其实也可以只用css)。
<style>
* {
padding: 0;
margin: 0;
list-style: none;
}
#ul {
position: relative;
top: 0px;
left: 0px;
}
li {
width: 200px;
height: 100px;
margin: 10px;
background-color: #f00;
color: #fff;
text-align: center;
font-size: 60px;
transition: all 0.3s ease-out;
}
</style>
<div style="height: 300px;overflow: hidden;">
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
</div>
html
结构的大概意思就是,最外层的div
限制可视区域,使用js
移动ul
达到滚动的效果
- 主要的代码如下
const ul = document.getElementById('ul')
const firstLi = document.querySelector('#ul li:first-child')
setInterval(() => {
const firstLi = document.querySelector('#ul li:first-child')
ul.style.transition = 'all 0.5s ease-out'
firstLi.style.opacity = 0
ul.style.top = -110 + 'px'
setTimeout(() => {
firstLi.removeAttribute('style')
ul.appendChild(firstLi)
ul.style.transition = ''
ul.style.top = 0
}, 500)
}, 2000)
这里有几个地方要注意
- 首先每两秒滚动一次,每次滚动的距离
-110px
,这个距离就是每个li
加上它margin
。 - 在
ul
滚动完成后我们需要移除第一个li
,把它加入到ul
的最后,但是这里会有一个问题,如果在ul.style.top = -110 + 'px'
之后直接ul.appendChild(firstLi)
,会导致第一个元素消失后,第二个元素就会顶上去,实际在页面上看到的不是预期的第二个元素而是第三个元素。所以这里在移除第一个元素之后,马上将ul
的位置重置为0 - 可以看到在
append
的时候我使用了一个500
毫秒的定时器,这里是因为我的过渡动画用的是css
,没办法知道他什么时候结束(除非使用animation可以事件监听),所以使用了一个大于之前设定的过渡动画时间的定时器,在动画完成后再移除第一个元素
3. 总体代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
list-style: none;
}
#ul {
position: relative;
top: 0px;
left: 0px;
}
li {
width: 200px;
height: 100px;
margin: 10px;
background-color: #f00;
color: #fff;
text-align: center;
font-size: 60px;
transition: all 0.3s ease-out;
}
</style>
</head>
<body>
<div style="height: 300px;overflow: hidden;">
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
</div>
<button id="start">走起来</button>
<button id="reset">复位</button>
<script>
const ul = document.getElementById('ul')
const start = document.getElementById('start')
const reset = document.getElementById('reset')
let timerId
start.onclick = () => {
if(timerId) return
timerId = setInterval(() => {
const firstLi = document.querySelector('#ul li:first-child')
ul.style.transition = 'all 0.5s ease-out'
firstLi.style.opacity = 0
ul.style.top = -110 + 'px'
setTimeout(() => {
firstLi.removeAttribute('style')
// 模拟随机添加数据
// const count = Math.random() * 10
// for(let i = count; i >0; i--) {
// ul.appendChild(firstLi.cloneNode(true))
// }
ul.appendChild(firstLi)
ul.style.transition = ''
ul.style.top = 0
}, 500)
}, 2000)
}
reset.onclick = () => {
clearInterval(timerId)
timerId = undefined
location.reload()
}
</script>
</body>
</html>
网友评论