前端js控制元素移动

ops/2024/9/22 23:34:53/

背景

页面中有多个表格,每个表格中均有一从右到左匀速移动的元素,随着元素移动需要在表格中增减数据,由于使用css3动画无法捕捉元素移动位置,所以这里采用js控制dom的写法

解决办法

最终代码放在文章的最后,各位看官可以跳过这里直接取用。
思路如下,首先我采用了scrollLeft+setInterval进行试验,发现使用scrollLeft只能让内部元素最右侧和外部元素左右侧重合就无法继续滚动了
在这里插入图片描述

javascript"><!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,发现成功了,内部元素可以从右至左滚动至完全消失
在这里插入图片描述

javascript"><!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,用于在下一次重绘之前执行动画。它可以让浏览器在下一次重绘之前调用指定的函数更新动画。这个函数的主要优点是它可以自动匹配显示器的刷新率,从而实现更平滑的动画效果。

最终代码

在这里插入图片描述

javascript"><!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>

http://www.ppmy.cn/ops/8901.html

相关文章

学习前端第二十四天(对象的引用和复制,对象方法,this)

一、对象的引用和复制 赋值了对象的变量存储的不是对象本身&#xff0c;而是该对象“在内存中的地址”&#xff0c;对象储存着变量的地址。 所以当一个对象变量被复制 &#xff0c;其实是另一个对象复制了这个对象的引用&#xff0c;而该对象自身并没有被复制。 现在我们有了…

AI Agent应用项目

AI Agent应用项目广泛涉及多个领域,包括但不限于旅游和酒店业、制造、医疗、金融、教育、零售等。在旅游和酒店业中,AI Agent能够提供自然、流畅和个性化的客户交互服务,如信息咨询、预订、退订、投诉等1。在制造业中,AI Agent通过语音识别和自然语言处理技术为操作工人提供…

10-菜刀连接木马

找到了漏洞后&#xff0c;并且上传了木马之后才能使用的两款工具 中国菜刀和冰蝎 想办法获取别人的cookie&#xff0c;cookie中有session-id 一、中国菜刀 1、必须提前已经完成木马植入然后才能使用 2、木马必须是POST请求&#xff0c;参数自定义&#xff0c;在菜刀里给出…

关于分布式事务的raft算法

raft算法保证一致性和分区容错性&#xff0c;通过领导选举和日志复制保证一致性&#xff0c;即使分区错误也能保证一致性&#xff0c; 自旋时间来保证能不能当领导 心跳时间&#xff0c;发送日志 简单来说就是所有的节点自旋&#xff0c;然后时间先到的节点给其他节点发送投票申…

Java工具类:封装Okhttp实现:Get、Post、上传/下载文件、Stream响应、代理ip

不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 一、介绍 本文代码是引入Okhttp_v4.11.0,在这个基础上进行二次封装使调用方更加容易,只关注业务,而无需处理各种请求相关的重复性操作,类似文件类型请求体封装或者Form表单构造及body传参等一系列处理工具代码包括但不限…

信号继电器HBDXH-200/1辅助电源110VDC 启动电压110VDC JOSEF约瑟

用途 适用于直流操作的继电保护和自动控制线路中&#xff0c;作为信号指示用&#xff0c;有多组动合保持触点。满足现场指示和遥信要求。 技术参数 启动信号额定值:直流电流型:10mA~4A. 直流电压型:220VDC、110VDC、48VDC、24VDC 辅助电源电压:220VDC、110VDC、220VAC、110…

牛客NC197 跳跃游戏(一)【中等 动态规划 Java、Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/23407eccb76447038d7c0f568370c1bd 思路 答案说的merge区间就是每个A[i]的地方能跳到的最远坐标是A[i] [i]&#xff0c; 有一个maxReach&#xff0c;遍历一遍A[i], 不断刷新MaxReach, 如果某个i 位置比maxReac…

Vue之v-on事件修饰符的含义及使用

背景&#xff1a;Vue 拆封了一个组件&#xff0c;在组件里面会使用一个方法来改变父组件传过来的值&#xff0c; 但是在子组件里面操作父组件的数据变更&#xff0c;实在比较麻烦&#xff08;因为单向数据流&#xff09;&#xff0c; So 能不能直接在组件上面绑定事件方法呢&…