写轮播图时,关于offsetX和pageX的选择以及一些坑

article/2025/11/8 22:33:53

一、不要使用offsetX

        前几天在公司实习,由于使用了swiper来做c端的滑动效果,在自定义的过程中,出现了一系列的坑,我看了源码,看了文档,也还是没有很好的理解,这个swiper的标准操作流程,当时,就想到能不能自己写一个轮播图上去,于是也就又了下文。

        大家都知道,其实轮播图的本质还是很简单的,就是在点击的时候,获得两个值,一个是当前包裹层的left值,一个是鼠标点击包裹层外面的展示层(也就是overflow:hidden的最外层)时的鼠标位置。这个包裹层的left值,如果想用offsetLeft的话,千万要记住直接在dom上取就好了,style上是没有的!!!,呀呀呀!我就被坑了足足五分钟,才想到!!!如果是left的话就在style上找就好了,left和offset在展示层设置了position之后,在做轮播图上没有什么区别,都是一样的。

        但是,那个点击事件中的如果用了offsetX,那么酸爽的闪跳就要开始了!

mousedown = (e) => {this.flag = trueconst { offsetX: X } = e// 点击这个offsetX成了与img的left距离// const { pageX: X } = e// 先拿到了 container 相对于 页面 的 位置 x ythis.startX = X;this.startLeft = parseInt(this.mycontainer.offsetLeft || 0)// 这里选择offsetLeft 一直都取不到数值啊 原来不在style上啊 !!// this.startLeft = parseInt(this.mycontainer.style.left || 0)return false}
mousemove = (event) => {if (this.flag) {event.preventDefault()const { offsetX: moveX } = event // offsetX最大只是能200console.log("move offsetX", moveX)let offsetLeft = moveX - this.startX;this.mycontainer.style.left = `${-offsetLeft + this.startLeft}px`// 上面要注意 类型没有为整数时 直接字符串+字符串 也是闪跳的原因之一 }return false}

        上面这个是addEventListener的两个函数,分别用于点击和移动。

闪跳的原因

        闪跳的原因其实本质上就是left的忽然变大或者变小,围绕这个原因,我发现了两处很有可能发生left值突然的变化的地方。

        第一个是,我一开始选择的是,在点击的时候,拿到left,但是left大家都知道,left拿到的是一个带px的字符串,我天真的以为把字符串“px”去掉了,然后字符串加上一个数字自动就会转化为数字了,结果出现了一下子left值变成了 34 + “34” = “3434” 这样的悲剧,关键当时我还像下图一样,加了一个Number,直接导致,图像瞬间移动,不过这个闪跳还是比较好发现的

this.mycontainer.style.left = `${Number(-offsetLeft + this.startLeft)}px`

        第二个就是关于 offsetX的问题了,先来考考大家,offsetX的是鼠标到哪里的距离呢,绝大多数人,可能会回答就像是offsetLeft一样,是相对于其父级的,但是这个在event事件中的offsetX就是不成立的了,网上对于offsetX的描述非常少,但是我觉得一句话说得非常好,事件发生时鼠标相对于事件源元素的坐标,而这个源元素是什么呢?我觉得是event.target的那个,下面我将用这次自己出现的问题来验证这个源元素。

         这个问题的出现,将直接影响一个效果,那就是闪跳,当你从左图点击时,你的初始化的startX为150px(假设),而当你鼠标滑动到右图时,你的move的moveX一下子变为了0,而这时的你的left在会突然有一个较大的变化值,所以就会发生闪跳。

        PS:如果你将我的代码逻辑,改变一下,也就是图随之鼠标的移动而移动的话,只需要改变一行代码,即就是把下图的offsetLeft前面的负号去掉,这个offsetLeft是我设置的鼠标移动减去鼠标点击之后的偏移量,这样的话,不会出现我这个上面所展示的因为offsetX的源元素而导致的闪跳问题,但是也会出现图片移动过程中发抖,也就是offsetX获取的值会忽大忽小,原因也是比较简单,其实还是由于offsetX定位于img,所以img在移动的过程中,你的鼠标也在移动,如果你鼠标移动比较慢,因为,offsetX的计算应该与img有关,而img本身又会移动,所以会出现一些计算问题(当然这个是我比较粗浅的理解,大家可以自己尝试一下,这个抖动问题,因为我换成pageX,如果鼠标慢一点移动,确实基本没有抖动)。

            this.mycontainer.style.left = `${offsetLeft + this.startLeft}px`

   二、使用pageX

        当我使用pageX的时候,由于pageX是相对于整个页面的鼠标事件中的横坐标位置,所以用来计算偏移量真的是很好的选择了,轮播图的移动也会比较丝滑,代码的话,就是把event事件中的所以offsetX换成pageX,嗯,非常好用!!!!

   三、思考

        我觉得,用offsetX真的会出现效率问题,因为offsetX每次都需要在img变化之后,再次计算,也有可能就是渲染时机进一步导致抖动的!!!而pageX则一直直接与窗口计算,应该效率会高很多!!!


http://chatgpt.dhexx.cn/article/91iKfMmt.shtml

相关文章

js e.offsetX 和 e.offsetY

本人自己在写代码的过程中&#xff0c;一直对e.offsetX 与 e.offsetY 分不清&#xff0c;今天好好探究一下e.offsetX 与 e.offsetY e.offsetX 与 e.offsetY 下相对与事件源的距离&#xff0c;也就是距离e.target的距离&#xff0c; 大家看下面例子,给出几张截图。 <!DOCTY…

html5 offsetx,原生HTML5关于Div对象的.clientLeft、.offsetLeft、.clientX、.offsetX区分

本篇主要介绍clientLeft、offsetLeft、clientX、offsetX这四种元素属性的区别&#xff0c;首先我们要理解清楚它们的概念&#xff1a; clientLeft&#xff1a;该元素对象的左边框宽度。 clientWidth&#xff1a;该元素对象的左内边框至右内边框的距离。 offsetLeft&#xff1a;…

html5 offsetx,event对象中offsetX,clientX,pageX,screenX的区别

1、offsetX offset意为偏移量,是事件对象距左上角为参考原点的距离。以元素盒子模型的内容区域的左上角为参考点。不包括border。 2、clientX 事件对象相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条 3、pageX 事件对象相对于整个文档的坐标以像素…

彻底搞懂 offsetX、scrollX、clientX 的区别

无论在 iOS 还是前端开发中&#xff0c;关于如何定位一个元素是必须要掌握的知识&#xff0c;而在前端中&#xff0c;元素定位比较难理解&#xff0c;我们今天一起学习下。 在 DOM 设计中&#xff0c;主要通过这些 API 来确定某个元素的具体位置。 offsetTop, offsetLeft, offs…

Java数组赋值时内存中的变化

java中的方法区存放的是编译后的文件 xxx.class文件当创建数组对象时&#xff0c;数组对象会存放在堆里面&#xff0c;数据也存在于堆。当给数组赋值时&#xff0c;方法会进栈&#xff0c;然后拿着数组的地址去堆里面寻找数据并赋值

Java数组:用fill()方法给数组赋值

Arrays类可以在指定位置进行数值填充&#xff0c;但是只能使用同一个数值进行填充&#xff1a; Arrays.fill(Object[] a,Object value);a表示数组&#xff0c;value表示填充的值 例1 public static void main(String[] args) {int[] a new int[6];//声明创建一个数组System.o…

Java数组练习--数组随机赋值

随机数生成&#xff1a;使用Math.random()方法&#xff0c;即&#xff1a; [ 0 , 1 ) → [ 0 , 1 ) 30 → [0 ,30) [0 ,30) 1 → [1,31) 取整后范围是[1,30] 此题目要点是&#xff0c;赋值之后的数组元素&#xff0c;要与之前赋值元素的值比较&#xff…

java 数组的创建 与 赋值

1.2.2 数组类型 基本类型的数组有3种赋值形式&#xff0c;如下所示&#xff1a; 第1种和第2种都是预先知道数组的内容&#xff0c;而第3种是先分配长度&#xff0c; 然后再给每个元素赋值。第3种形式中&#xff0c;即使没有给每个元素赋值&#xff0c;每个元素也都有一个默认值…

java 数组批量赋值_「数组赋值」java编程-定义数组并赋值 - seo实验室

数组赋值 package day03; public class TestArray { public static void main(String [] args) { int [] b; b new int[] {88,99,66}; //分步定义数组&#xff0c;先定义数组名&#xff0c;然后再为数组赋值 int [] d {88,99,100}; //直接定义数组&#xff0c;同时赋值 Syste…

java数组循环动态赋值_Java数组

Java语言数组遍历教程 Java语言数组遍历详解 语法 for(int i = 0;i< 数组名称.length;i++){数组名称[i]; } 说明 我们在程序中,定义了一个变量 i,用 i 的值和数组的长度值比较,因为数组的索引是从 0 开始的,所以我们遍历的数值只能够小于 数组名称.length。 数组存储的结…

Java数组的赋值机制

数组的两种赋值的方式 引用传递&#xff0c;赋的是地址 数组的值是放在JVM的堆里&#xff0c;当定义一个数组时会在JVM里的栈中&#xff0c;放置堆的地址&#xff0c;来指向JVM对应的 堆 。在对数组进行赋值的时候&#xff0c;默认情况下是引用传递&#xff0c;即把堆的地址给…

Java二维数组赋值

Java二维数组是指由多个一维数组组成的数组结构。它可以看作是一个表格&#xff0c;其中行表示数组中的第一个维度&#xff0c;列表示第二个维度。 可以使用两个方括号&#xff08;[ ] [ ]&#xff09;来声明和访问Java二维数组中的元素。 例如&#xff0c;以下代码声明了一个包…

java数组赋值_java中给数组赋值的方法

1、数组操作中&#xff0c;可以使用等于()赋值 注意&#xff1a;此时新数组只是指向原数组的存储空间&#xff0c;并没有重新申请新的空间。 实例&#xff1a;public class ArrayTest{ public static void main(String args[]){ // 1 int[] anew int[4]; a[0]1; a[1]2; a[2]3; …

Java数组变量赋值

一、问题&#xff1a;Java数组变量赋值是值传递还是址传递&#xff1f; 1.1 结论&#xff1a;java变量赋值是址传递 1.2 验证过程&#xff1a; ​ public class Test {public static void main(String[] args) {int[] arryA {1, 2, 3};int[] arryB {4, 5, 6, 7};arryA ar…

java 数组赋值_java中为数组赋值的方法

java中为数组赋值的方法 发布时间&#xff1a;2020-06-25 14:31:36 来源&#xff1a;亿速云 阅读&#xff1a;184 作者&#xff1a;Leah 这期内容当中小编将会给大家带来有关java中为数组赋值的方法&#xff0c;文章内容丰富且以专业的角度为大家分析和叙述&#xff0c;阅读完这…

【自学Java】Java语言数组赋值

Java语言数组赋值 Java数组赋值教程 在 Java 语言 中&#xff0c;给 数组 赋值&#xff0c;就相当于给每个位置上的对应的位置填充数据。 Java语言数组赋值详解 Java 中的数据赋值分为动态化赋值和静态化赋值两种赋值方式。动态化赋值指的是先定义数组&#xff0c;然后指定…

Java数组赋值数组复制(拷贝)

Java数组赋值&数组复制(拷贝) 数组赋值数组复制 1⃣️数组赋值 值传递(基本数据类型)与引用传递(数组)区别 值传递&#xff1a;基本数据类型赋值&#xff0c;赋给变量的值就是具体的数据&#xff0c;而且相互不受影响&#xff1b; int a 10; int b a; // b的变化不会影…

LATEX换行

LATEX 换行 \ newpage \maketitle 表示 begin{document} 前面的标题在这里显示 begin{document} 中的文本才显示

latex换行后(\\)如何继续缩进两格?

LaTeX 中正常换行不要使用 \&#xff0c;直接回bai车两下&#xff0c;即du在两段中间空一行&#xff0c;这样就会自动另zhi起一段并且缩dao进了。 也可以在段落前面加上 \par &#xff0c;例如 \par 第一段。\par 第二段。 就可以将它们分段了&#xff0c;如果想要在强制换行…

Latex: 表格中 自动换行居中

1、在导言区添加宏包&#xff1a; \usepackage{makecell}2、环境&#xff1a;tabular 命令&#xff1a; \makecell[居中情况]{第1行内容 \\ 第2行内容 \\ 第3行内容 ...} \makecell [c]{ResNet101\\ (11.7M)}参数说明&#xff1a; [c]是水平居中&#xff0c;[l]水平左居中&am…