背景
页面中有多个表格,每个表格中均有一从右到左匀速移动的元素,随着元素移动需要在表格中增减数据,由于使用css3动画无法捕捉元素移动位置,所以这里采用js控制dom的写法
解决办法
最终代码放在文章的最后,各位看官可以跳过这里直接取用。
思路如下,首先我采用了scrollLeft+setInterval进行试验,发现使用scrollLeft只能让内部元素最右侧和外部元素左右侧重合就无法继续滚动了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚动</title>
<style>
* {
margin: 0;
padding: 0;
}
#wrapper {
cursor: pointer;
width: 600px;
height: 200px;
border: 1px solid pink;
overflow: hidden;
display: flex;
margin: auto;
}
#list {
display: flex;
}
#list {
margin-left: 600px;
}
.item {
width: 200px;
height: 200px;
flex-shrink: 0;
text-align: center;
line-height: 200px;
}
.item:nth-child(odd) {
background: skyblue;
}
.item:nth-child(even) {
background: yellow;
}
</style>
</head>
<body>
<!-- 外层盒子 -->
<div id="wrapper">
<!-- 内部滚动盒子 -->
<div id="list">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
</div>
</div>
<script>
window.onload = function () {
let speed = 10;
let tab = document.getElementById("wrapper");
let tab1 = document.getElementById("list");
function handleScroll() {
if (tab1.offsetWidth - tab.scrollLeft <= 0) { clearInterval(timer) }
else {
tab.scrollLeft++;
}
}
let timer = setInterval(handleScroll, speed);
}
</script>
</body>
</html>
于是我用translateX代替scrollLeft,发现成功了,内部元素可以从右至左滚动至完全消失
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚动</title>
<style>
* {
margin: 0;
padding: 0;
}
#wrapper {
cursor: pointer;
width: 600px;
height: 200px;
border: 1px solid pink;
overflow: hidden;
display: flex;
margin: auto;
}
#list {
display: flex;
}
#list {
margin-left: 600px;
}
.item {
width: 200px;
height: 200px;
flex-shrink: 0;
text-align: center;
line-height: 200px;
}
.item:nth-child(odd) {
background: skyblue;
}
.item:nth-child(even) {
background: yellow;
}
</style>
</head>
<body>
<!-- 外层盒子 -->
<div id="wrapper">
<!-- 内部滚动盒子 -->
<div id="list">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
</div>
</div>
<script>
window.onload = function () {
let speed = 10;
let scrollLength = 0;
let tab = document.getElementById("wrapper");
let tab1 = document.getElementById("list");
function handleScroll() {
if (tab1.offsetWidth + tab.offsetWidth < scrollLength) {
clearInterval(timer)
}
else {
scrollLength = scrollLength + 1;
tab1.style.transform = 'translateX(-' + scrollLength + 'px)';
}
}
let timer = setInterval(handleScroll, speed);
}
</script>
</body>
</html>
但是上述方法还有一个问题就是,当前页面有多个滚动元素,即会有多个定时器,由于不断地重绘,导致了页面卡顿,造成了两个相同的滚动元素滚动速度不一致的问题,于是我使用requestAnimationFrame代替setInterval解决了问题
requestAnimationFrame 是一个浏览器提供的 API,用于在下一次重绘之前执行动画。它可以让浏览器在下一次重绘之前调用指定的函数更新动画。这个函数的主要优点是它可以自动匹配显示器的刷新率,从而实现更平滑的动画效果。
最终代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚动</title>
<style>
* {
margin: 0;
padding: 0;
}
#wrapper {
cursor: pointer;
width: 600px;
height: 200px;
border: 1px solid pink;
overflow: hidden;
display: flex;
margin: auto;
}
#list {
display: flex;
}
#list {
margin-left: 600px;
}
.item {
width: 200px;
height: 200px;
flex-shrink: 0;
text-align: center;
line-height: 200px;
}
.item:nth-child(odd) {
background: skyblue;
}
.item:nth-child(even) {
background: yellow;
}
</style>
</head>
<body>
<!-- 外层盒子 -->
<div id="wrapper">
<!-- 内部滚动盒子 -->
<div id="list">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
</div>
</div>
<script>
window.onload = function () {
let speed = 10;
let scrollLength = 0;
let tab = document.getElementById("wrapper");
let tab1 = document.getElementById("list");
function handleScroll() {
if (tab1.offsetWidth + tab.offsetWidth > scrollLength) {
scrollLength = scrollLength + 1;
tab1.style.transform = 'translateX(-' + scrollLength + 'px)';
requestAnimationFrame(handleScroll);
}
}
requestAnimationFrame(handleScroll);
}
</script>
</body>
</html>