我需要一个用户列表来垂直无限循环。 我知道我应该对这类内容使用“ translateY”而不是“ top”-但我不知道如何。 我已经完成了“热门”版本,并且可以使用。有什么想法可以改善它吗?
谢谢大家!
<table class="userList w990 marginTop10">
<tbody>
<tr>
<th class="w195 whiteFont leftAlign">Status</th>
<td class="even width150" id="status">Active</td>
<th class="w195 whiteFont leftAlign">Name</th>
<td class="even" id="name"> NATESAN</td>
</tr>
</tbody>
</table>
答案 0 :(得分:1)
这是我的尝试:
new Vue({
el: '#app',
data() {
const rows = []
for (let i = 0; i < 30; i++) {
rows.push({
id: i
})
}
return {
offset: 0,
rows
}
},
mounted () {
this.frameTime = Date.now()
const animate = () => {
this.animationId = requestAnimationFrame(() => {
this.update()
animate()
})
}
animate()
},
beforeDestroy () {
cancelAnimationFrame(this.animationId)
},
methods: {
update() {
const now = Date.now()
const elapsed = now - this.frameTime
this.offset -= elapsed / 16
this.frameTime = now
if (this.offset < -400) {
while (this.offset < -40) {
this.rows.push(this.rows.shift())
this.offset += 40
}
}
}
}
})
* {
box-sizing: border-box;
}
#rows {
border: 1px solid #f00;
height: 200px;
overflow: hidden;
}
.row {
width: 100%;
height: 40px;
border: 2px solid black;
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<div id="rows">
<div :style="{ transform: `translateY(${Math.round(offset)}px)` }">
<div
v-for="row in rows"
:key="row.id"
class="row"
>
{{row.id}}
</div>
</div>
</div>
</div>
您不一定必须进行我所做的所有更改,如果愿意,可以有选择地进行大多数更改。主要变化是:
key
,以便Vue在发生混洗时移动DOM节点,而不是更新所有DOM节点。<div>
,这样实际上只有一个元素在移动(为此,我摆脱了绝对定位)。translateY
。setInterval
,您只需要requestAnimationFrame
。通过跟踪经过了多少时间来检查动画速度。更新:
三个进一步的变化:
box-sizing: border-box
来解决计算中2px的误差。translateY
舍入为整像素。对我来说,这看起来稍微好一点,但是在像素比率更高的屏幕上,我可以想象它看起来会更糟。
视情况而定,还有其他优化可能适用。
translateY
可以完全避免重新排序,尽管对于很多行来说可能并不实际。使用过渡或CSS动画对此进行动画处理将非常棘手,因为需要将行向下跳回到底部。如果每一行都独立设置动画,我不确定保持所有动画同步有多么容易。