最新要闻
- 抖音小店运营没有头绪?一定要掌握这些技巧!全篇详解! 当前简讯
- 芒果TV五一狂促:会员年卡3折年内新低 仅79元
- 我国小行星防御首次任务计划公布:2030年对小行星动能撞击 世界播报
- 还买啥RTX 4070 AMD铁了心降价:16GB显存RX 6950 XT只要4749元_世界头条
- 豆瓣评分高达9.0!《灌篮高手》遭遇史上最严重盗摄|速读
- 热点评!别急着升级!火狐浏览器112稳定版出内存泄露Bug
- in fear(fearitself)|全球聚焦
- 遵义12岁失联女孩被找到,一细节披露令人不解,嫌疑人已被抓获
- 世纪天鸿涨停 三个交易日机构净买入1.41亿元
- 国产武侠开放世界沙盒生存游戏 《侠乂行:浪迹天涯》预售:128元 环球快资讯
- 男子高速要求停车上厕所被拒后跳车 专家科普:极其危险 环球要闻
- 今日报丨铭瑄RTX 4070 iCraft OC12G瑷珈显卡评测:专为2K高画质而生 DLSS 3畅享百帧光追
- 天天微速讯:比亚迪盘活腾势!全新猎跑SUV腾势N7盲订7天订单破万
- 1亿像素仅1399元 荣耀X50i开箱图赏 世界今亮点
- 三年来北京为3万余名务工人员追发工资5.11亿元-世界速看料
- 山东海化: 关于会计政策变更的独立意见|焦点简讯
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
记录-因为写不出拖拽移动效果,我恶补了一下Dom中的各种距离
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
背景
最近在项目中要实现一个拖拽头像的移动效果,一直对JS Dom拖拽这一块不太熟悉,甚至在网上找一个示例,都看得云里雾里的,发现遇到最大的拦路虎就是JS Dom各种各样的距离,让人头晕眼花,看到一个距离属性,大脑中的印象极其模糊,如同有一团雾一样,不知其确切含义。果然是基础不牢,地动山摇。今天决心夯实一下基础,亲自动手验证一遍dom各种距离的含义。
JS Dom各种距离释义
下面我们进入正题, 笔者不善于画图, 主要是借助浏览器开发者工具,通过获取的数值给大家说明一下各种距离的区别。
第一个发现 window.devicePixelRatio 的存在
本打算用截图软件丈量尺寸,结果发现截图软件显示的屏幕宽度与浏览器开发者工具获取的宽度不一致,这是为什么呢?
- 截图软件显示的屏幕宽度是1920
- window.screen.width显示的屏幕宽度是1536
这是怎么回事?原来在PC端,也存在一个设备像素比的概念。它告诉浏览器一个css像素应该使用多少个物理像素来绘制。要说设备像素比,得先说一下像素和分辨率这两个概念。
- 像素屏幕中最小的色块,每个色块称之为一个像素(Pixel)
- 分辨率分辨率=屏幕水平方向的像素点数 * 屏幕垂直方向的像素点数; 另外说一下,关于分辨率有多种定义,可以细分为显示分辨率、图像分辨率、打印分辨率和扫描分辨率等,此处是指显示分辨率。
- 设备像素比
设备像素比的定义是:
window.devicePixelRatio
=显示设备物理像素分辨率显示设备CSS像素分辨率\frac{显示设备物理像素分辨率}{显示设备CSS像素分辨率}显示设备CSS像素分辨率显示设备物理像素分辨率
根据设备像素比的定义, 如果知道显示设备横向的css像素值,根据上面的公式,就能计算出显示设备横向的物理像素值。
显示设备宽度物理像素值= window.screen.width * window.devicePixelRatio;
设备像素比在我的笔记本电脑上显示的数值是1.25, 代表一个css逻辑像素对应着1.25个物理像素。
我前面的公式计算了一下,与截图软件显示的像素数值一致。这也反过来说明,截图软件显示的是物理像素值。
- window.devicePixelRatio 是由什么决定的 ?
发现是由笔记本电脑屏幕的缩放设置决定的,如果设置成100%, 此时window.screen.width与笔记本电脑的显示器分辨率X轴方向的数值一致,都是1920(如右侧图所示), 此时屏幕上的字会变得比较小,比较伤视力。
- 逻辑像素是为了解决什么问题?
逻辑像素是为了解决屏幕相同,分辨率不同的两台显示设备, 显示同一张图片大小明显不一致的问题。比如说两台笔记本都是15英寸的,一个分辨率是1920*1080
,一个分辨率是960*540
, 在1920*1080
分辨率的设备上,每个格子比较小,在960*540
分辨率的设备上,每个格子比较大。一张200*200
的图片,在高分率的设备上看起来会比较小,在低分辨率的设备上,看起来会比较大。观感不好。为了使同样尺寸的图片,在两台屏幕尺寸一样大的设备上,显示尺寸看起来差不多一样大,发明了逻辑像素这个概念。规定所有电子设备呈现的图片等资源尺寸统一用逻辑像素表示。然后在高分辨率设备上,提高devicePixelRatio, 比如说设置1920*1080
设备的devicePixelRatio(dpr)等于2, 一个逻辑像素占用两个格子,在低分辨率设备上,比如说在960*540
设备上设置dpr=1, 一个css逻辑像素占一个格子, 这样两张图片在同样的设备上尺寸大小就差不多了。通常设备上的逻辑像素是等于物理像素的,在高分辨率设备上,物理像素是大于逻辑像素数量的。由此也可以看出,物理像素一出厂就是固定的,而设备的逻辑像素会随着设备像素比设置的值不同而改变。但图片的逻辑像素值是不变的。
document.body、document.documentElement和window.screen的宽高区别
差别是很容易辨别的,如下图所示:
- document.body -- body标签的宽高
- document.documentElement -- 网页可视区域的宽高(不包括滚动条)
- window.screen -- 屏幕的宽高
- 网页可视区域不包括滚动条
如下图所示,截图时在未把网页可视区域的滚动条高度计算在内的条件下, 截图工具显示的网页可视区域高度是168, 浏览器显示的网页可视区域的高度是167.5, 误差0.5,由于截图工具是手动截图,肯定有误差,结果表明,网页可视区域的高度 不包括滚动条高度。宽度同理。
- 屏幕和网页可视区域的宽高区别如下:
屏幕宽高是个固定值,网页可视区域宽高会受到缩放窗口影响。
- 屏幕高度和屏幕可用高度区别如下:
屏幕可用高度=屏幕高度-屏幕下方任务栏的高度,也就是:
window.screen.availHeight = window.screen.height - 系统任务栏高度
scrollWidth, scrollLeft, clientWidth关系
scrollWidth(滚动宽度,包含滚动条的宽度)=scrollLeft(左边卷去的距离)+clientWidth(可见部分宽度);// 同理scrollHeight(滚动高度,包含滚动条的高度)=scrollTop(上边卷去的距离)+clientHeight(可见部分高度);
需要注意的是,上面这三个属性,都取的是溢出元素的父级元素属性。而不是溢出元素本身。本例中溢出元素是body(document.body),其父级元素是html(document.documentElement)。另外,
溢出元素的宽度(document.body.scrollWidth)=父级元素的宽度(document.documentElement.scrollWidth) - 滚动条的宽度(在谷歌浏览器上滚动条的宽度是19px)
JS Dom各种距离
元素自身和父级元素的scrollWidth和scrollLeft关系?
从下图可以看出:
- 元素自身没有X轴偏移量,元素自身的滚动宽度不包含滚动条
- 父级元素有X轴便宜量, 父级元素滚动宽度包含滚动条
JS Dom各种距离 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111<script></script>
offsetWidth和clientWidth的关系?
offsetWidth和clientWidth的共同点是都包括 自身宽度+padding , 不同点是offsetWidth包含border。
如下图所示:
- rect元素的clientWidth=200px(自身宽度) + 20px(左右padding) = 220px
- rect元素的offsetWidth=200px(自身宽度) + 20px(左右padding) + 2px(左右boder) = 222px
JS Dom各种距离 111111111111111111111111111111111111111111111111<script></script>
event.clientX,event.clientY, event.offsetX 和 event.offsetY 关系
代码如下,给rect元素添加一个mousedown事件,打印出事件源的各种位置值。
JS Dom各种距离 <script> const rectDom = document.querySelector("#rect"); rectDom.addEventListener("mousedown", ({ offsetX, offsetY, clientX, clientY, pageX, pageY, screenX, screenY }) => { console.log({ offsetX, offsetY, clientX, clientY, pageX, pageY, screenX, screenY }); })</script>
我们通过y轴方向的高度值,了解一下这几个属性的含义。 绿色块的高度是50px, 我们找个特殊的位置(绿色块的右小角)点击一下,如下图所示:
- offsetY=49, 反推出这个值是相对于元素自身的顶部的距离
- clientY=69, body标签的border-top是10,paiding是10, 反推出这个值是相对网页可视区域顶部的距离
- screenY=140,目测肯定是基于浏览器窗口,
所以它们各自的含义,就很清楚了。
事件源属性 | 表示的距离 |
---|---|
event.offsetX、event.offsetY | 鼠标相对于事件源元素(srcElement)的X,Y坐标, |
event.clientX、event.clientY | 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动偏移量。 |
event.pageX、event.pageY | 鼠标相对于文档坐标的x,y坐标,文档坐标系坐标 = 视口坐标系坐标 + 滚动的偏移量 |
event.screenX、event.screenY | 鼠标相对于用户显示器屏幕左上角的X,Y坐标 |
- pageX和clientX的关系
我们点击下图绿色块的右下角,把pageX和clientX值打印出来。如下图所示:
- 可视区域的宽度是360,点击点的clientX=359(由于是手动点击,有误差也正常)
- 水平方向的偏移量是56
- pageX是415,360+56=416,考虑到点击误差,可以推算出
ele.pageX = ele.clientX + ele.scrollLeft
getBoundingClientRect获取的top,bottom,left,right的含义
从下图可以看出,上下左右这四个属性,都是相对于浏览器可视区域左上角而言的。
从下图可以看出,当有滚动条出现的时候,right的值是359.6,而不是360+156(x轴的偏移量), 说明通过getBoundingClientRect获取的属性值是不计算滚动偏移量的,是相对浏览器可视区域而言的。
想移动元素,mouse和drag事件怎么选?
mouse事件相对简单,只有mousedown(开始),mousemove(移动中),mouseup(结束)三种。与之对应的移动端事件是touch事件,也是三种touchstart(手指触摸屏幕), touchmove(手指在屏幕上移动), touchend(手指离开屏幕)。
相对而言, drag事件就要丰富一些。
- 被拖拽元素事件
事件名 | 触发时机 | 触发次数 |
---|---|---|
dragstart | 拖拽开始时触发一次 | 1 |
drag | 拖拽开始后反复触发 | 多次 |
dragend | 拖拽结束后触发一次 | 1 |
- 目标容器事件
事件名 | 触发时机 | 触发次数 |
---|---|---|
dragenter | 被拖拽元素进入目标时触发一次 | 1 |
dragover | 被拖拽元素在目标容器范围内时反复触发 | 多次 |
drop | 被拖拽元素在目标容器内释放时(前提是设置了dropover事件) | 1 |
想要移动一个元素,该如何选择这两种事件类型呢? 选择依据是:
类型 | 选择依据 |
---|---|
mouse事件 | 1. 要求丝滑的拖拽体验 2. 无固定的拖拽区域 3. 无需传数据 |
drag事件 | 1. 拖拽区域有范围限制 2. 对拖拽流畅性要求不高 3. 拖拽时需要传数据 |
现在让我们写个拖拽效果
光说不练假把式, 扫清了学习障碍后,让我们自信满满地写一个兼容PC端和移动端的拖动效果。不积跬步无以至千里,幻想一口吃个胖子,是不现实的。这一点在股市上体现的淋漓尽致。都是有耐心的人赚急躁的人的钱。所以,要我们沉下心来,打牢基础,硬骨头啃一点就会少一点,步步为营,稳扎稳打,硬骨头也会被啃成渣。
拖拽水潭 <script> let evtName = getEventName(); // 确保图片加载完 window.onload = () => { let offsetX = 0, offsetY = 0; // const water = document.querySelector(".water"); const moveAt = ({ pageX, pageY }) => { water.style.cssText = `left:${pageX - offsetX}px;top:${pageY - offsetY}px;`; }; water.addEventListener(evtName.start, (event) => { // 足球的偏移距离是针对球体表面, 不能把球体表面到球内鼠标位置的距离算在内 // 否则足球一移动,就会出现向下,向右不自然的偏移 offsetX = event.clientX - water.getBoundingClientRect().left; offsetY = event.clientY - water.getBoundingClientRect().top; // 设置初始偏移 moveAt(event); //监听鼠标相对于可视窗口移动的距离 document.addEventListener(evtName.move, moveAt); }); //拖动停止时,释放document上绑定的移动事件 // 不然移动鼠标,不拖拽时白白产生性能开销 water.addEventListener(evtName.end, () => { document.removeEventListener(evtName.move, moveAt); }); }; // 区分是移动端还是PC端移动事件 function getEventName() { if ("ontouchstart" in window) { return { start: "touchstart", move: "touchmove", end: "touchend", }; } else { return { start: "mousedown", move: "mousemove", end: "mouseup", }; } } </script>
彩蛋
在chrome浏览器上发现一个奇怪的现象,设置的border值是整数,计算出来的值却带有小数
而当border值是4的整数倍的时候,计算值是正确的
看了这篇文章解释说,浏览器可能只能渲染具有整数物理像素的border值,不是整数物理像素的值时,计算出的是近似border值。这个解释似乎讲得通,在设备像素比是window.devicePixelRatio=1.25的情况下, 1px对应的是1.25物理像素,1.25*4的倍数
才是整数,所以设置的逻辑像素是4的整数倍数,显示的渲染计算值与设置值一致,唯一让人不理解的地方,为什么padding,margin,width/height却不遵循同样的规则。本文转载于:
https://juejin.cn/post/7225206098692407355
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
关键词:
-
Java中为什么重写equals()也需要重写hashCode()?
所有类默认继承Object类先看一下Object源码packagejava lang;publicclassObject{ 默认调用本地的hashcode(
来源: 记录-因为写不出拖拽移动效果,我恶补了一下Dom中的各种距离
每日资讯:【谷歌插件开发】获取当前网站COOKIE并上报HTTP-API
Java中为什么重写equals()也需要重写hashCode()?
抖音小店运营没有头绪?一定要掌握这些技巧!全篇详解! 当前简讯
债市日报:4月25日_环球消息
芒果TV五一狂促:会员年卡3折年内新低 仅79元
我国小行星防御首次任务计划公布:2030年对小行星动能撞击 世界播报
还买啥RTX 4070 AMD铁了心降价:16GB显存RX 6950 XT只要4749元_世界头条
豆瓣评分高达9.0!《灌篮高手》遭遇史上最严重盗摄|速读
热点评!别急着升级!火狐浏览器112稳定版出内存泄露Bug
in fear(fearitself)|全球聚焦
遵义12岁失联女孩被找到,一细节披露令人不解,嫌疑人已被抓获
世纪天鸿涨停 三个交易日机构净买入1.41亿元
国产武侠开放世界沙盒生存游戏 《侠乂行:浪迹天涯》预售:128元 环球快资讯
男子高速要求停车上厕所被拒后跳车 专家科普:极其危险 环球要闻
今日报丨铭瑄RTX 4070 iCraft OC12G瑷珈显卡评测:专为2K高画质而生 DLSS 3畅享百帧光追
天天微速讯:比亚迪盘活腾势!全新猎跑SUV腾势N7盲订7天订单破万
1亿像素仅1399元 荣耀X50i开箱图赏 世界今亮点
三年来北京为3万余名务工人员追发工资5.11亿元-世界速看料
06 内存(上)划分与组织内存-天天简讯
乌合之众再次上演,打工人将被AI一键淘汰?
谈谈持续集成,持续交付,持续部署之间的区别
记录一则ADG备库报错ORA-29771的案例|天天观速讯
全球热消息:数字孪生与元宇宙:虚拟与现实的奇妙对话
恒生指数25日收跌1.71% 互联网科技股集体走低 最资讯
山东海化: 关于会计政策变更的独立意见|焦点简讯
不怕打岔!微信推出“最近阅读”:近期阅读文章一键查
腾讯携手Unity:推出定制化实时导航3D地图|天天热消息
金属马达+双滚珠轴承!酷冷至尊莫比乌斯120 OC风扇图赏|快播报
吉林长春现实版“虎口拔牙” 医生:从业20多年首次
焦点热议:拒还3亿退款!暴雪回应被网易起诉:目前未收到诉状
4月25日涨停板复盘:中科曙光涨停 中国科传11天7板
Java中不同对象调用该实例方法返回值是同一个地址空间吗?|天天最资讯
天天观焦点:Sftp工具类(跨服务器传输)
MySQL 备忘清单_开发速查表分享
头条:使用Dockerfile部署springboot打包jar包
【天天新要闻】仿Django框架-基于wsgiref模块和jinja2模块写一个简单的框架 主流框架简介 动静态网页 Python虚拟环境
火热征集中!全国城市生活垃圾分类标识征集大赛邀你来参与-世界新消息
收评:创指跌1.83%创近半年来新低 锂电池产业链跌幅靠前 天天热点
当前短讯!【财经分析】供应收缩叠加需求前景有望改善 原油止跌反弹
大气!蔚来宣布五一期间所有车主高速免费换电:不限次
47个楼盘2块钱甩卖!恒大汽车:只为专注造车
《古剑奇谭》开发商新作!类银河城游戏《心渊梦境》登陆PC/主机全平台
上海杭州之间或将建世界首条超级高铁:仅9分钟车程 全球热点
起诉苹果后 百度文心一言推出内测专用独立App:支持语音输入
坐下、抬爪、击掌……“毛孩子”们为患者带来欢乐与慰藉!
焦点快看:高质量数仓建模
火山引擎 DataLeap:在数据研发中,如何提升效率?
全球观点:数仓实践丨主动预防-DWS关键工具安装确认
支持全文检索、知识图谱、工作流审批的知识平台_天天时讯
【Mysql】复合主键的索引
安徽宿州:在房交会期间购买90平米以上新房,将给予每套10000元消费券
千万粉网红回应打卡徐州烧烤被网暴:不是黑 问题确实存在
“祝融号”火星车休眠近一年仍未唤醒 设计师回应:可能遭遇不可预知沙尘|微动态
睡个美容觉!马应龙蒸汽眼罩0.99元/片冲量大促 快看点
《赛博朋克2077》自研REDEngine出Bug:开启DLSS 3反而变卡 当前资讯
今日港股异动个股一览:中创新航(03931)现跌超5% 高盛称产能过剩或拖累利润率 产能扩张计划或提高杠杆水平_世界独家
吴镇宇14岁儿子官宣恋情!是日本无数宅男的女神
总裁赵伟与欧冶工业品公司领导座谈交流 时讯
扎克伯格醉心AI:Facebook或将更名MetAI
爱过的人我已不再拥有是什么歌?爱过的人我已不再拥有完整版歌词
终极系列正确观看顺序是什么?终极系列战力指数排名
双探的原型是什么?双探剧情介绍
天津德云鼓曲社升平雅乐特别奉献专场观演攻略 当前播报
光芒程亦治和丽姿第几集复婚的?光芒程亦治的身份是什么?
by2是双胞胎吗?by2个人资料介绍
强强联合,ByteHouse 携手亚马逊云科技,新一代云数仓服务重磅升级 世界新消息
全球通讯!深入理解C#泛型:new与where关键字全解析
使用docker 运行etcd 单实例/集群|环球播资讯
厦门市场监管部门发出“五一”旅游行业价格行为提醒告诫_天天速看
日本强推“排污入海”!学界:全球海洋生态将面临核污染水风险 全球信息
天天微速讯:自动泊车挑战立体车库 奔驰唯一成功 碾压华为、特斯拉
世界新资讯:特斯拉动能回收要彻底取消?博主辟谣:不实、只有两级可调
未上线就创纪录!《原神》开发商新作《崩坏:星穹铁道》iOS 113国登顶-热点
歼-20试飞员评价《长空之王》:很真实的影片
常欣科技2022年亏损30.64万同比由盈转亏 产品销售下降
要闻:彻底服了!这JB,NBA第一硬!黑8,必须黑8!
2023年宁德社保费用参考 宁德社保个人缴费标准是多少|速讯
iFlutter - 加速Flutter开发 环球消息
江西日报经济版头条 | 分宜工业经济高质量发展步履坚实
昭通昭阳富滇村镇银行获批解散 被富滇银行吸收合并 世界要闻
【环球财经】美国第一共和银行一季度业绩显著恶化
宋都基业投资股份有限公司发布公司股票可能被实施退市风险警示的第二次风险提示公告
东北地区及新疆等地有雨雪天气 江南华南有明显降雨过程
2023一卡逛崇川在哪里购买
今日报丨青岛口岸启运港退税政策宣传推介会举行
汽车也能戴“手表” 五菱宝骏悦也预告:行业首次搭载Car-watch
2499元 雷神MIX迷你主机上架:13代i5 比一罐可乐还小 世界快消息
商家浑水摸鱼 买到无码SteamDeck你肯定被骗了 全球观速讯
全球球精选!苹果影像破天荒升级!iPhone 15 Pro Max终于跟上安卓步伐了
今日热讯:恒大汽车暂缓生产恒驰5 全国交付量“感人”
广生泉:家政服务进社区
全球观天下!晋宁区开展“你点我检”食品安全专项抽检工作
安庆市养老金能提前支取吗 2023年安庆养老金如何计算 要闻速递
dnfyy是什么意思?dnfyy有哪些辅助频道?
首次发布!成都这个地方上火星了!
电压低是什么原因造成的?电压低对笔记本有影响吗?
戴尔inspiron 1440右侧卡槽干什么用?戴尔inspiron 1440配置
华为手机怎么获得root权限?华为手机怎么设置24小时时间显示?
[XXL-JOB] 分布式调度XXL-JOB快速上手 世界最新