一文彻底搞懂图解事件的坐标以及dom事件的属性,可视区域,
一.鼠标事件获取的位置信息
来源:一般是鼠标事件如click、dbclick、mousemove、mouseover等获取的位置信息。
事件对象可作为参数掺入事件处理函数中,事件对象中包含了许多有用的属性,例如:
clientX
和clientY
:鼠标相对于浏览器视口的位置。pageX
和pageY
:鼠标相对于整个文档的位置。screenX
和screenY
:鼠标相对于用户屏幕的位置。button
:表示哪个鼠标按钮被按下(0 = 左键,1 = 中键,2 = 右键)。target
:事件的目标元素。
下面对其中的坐标进行详细的介绍
如上图所示,假设页面中灰色圆点是鼠标点击处,黄色区域是鼠标触发事件对象。
综上:注意这里的坐标是鼠标点击的点,每次点击的不一样,坐标也是不一样的,即使你内容区还在原来的位置。 此外::::::注意page和client的区别::::::。
1、screenX 和screenY
-
参照点:电脑屏幕左上角
-
screenX:鼠标点击位置相对于电脑屏幕左上角的水平偏移量
-
screenY:鼠标点击位置相对于电脑屏幕左上角的垂直偏移量
2、clientX和clientY
-
参照点:浏览器内容区域左上角
-
clientX:鼠标点击位置相对于浏览器可视区域的水平偏移量(不会计算水平滚动的距离)
-
clientY:鼠标点击位置相对于浏览器可视区域的垂直偏移量(不会计算垂直滚动条的距离)
3、pageX和pageY
-
参照点:网页的左上角
-
pageX:鼠标点击位置相对于网页左上角的水平偏移量,也就是clientX加上水平滚动条的距离
-
pageY:鼠标点击位置相对于网页左上角的垂直平偏移量,也就是clientY加上垂直滚动条的距离
4、offsetX和offsetY
-
参照点:父元素
-
offsetX:鼠标点击位置相对于触发事件对象的水平距离
-
offsetY:鼠标点击位置相对于触发事件对象的垂直距离
二.dom事件的属性
1.位置和尺寸
都没有xxxright 和xxxbottom属性。
- offset系列 经常用于获得元素位置一共有5个相关值: offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop
offsetParent
很有用,因为offsetTop
和offsetLeft
都是相对于其内边距边界的。 - client经常用于获取元素大小 clientWidth、clientHeight、clientTop、clientLeft
- scroll 经常用于获取滚动距离 scrollTop、scrollLeft、scrollHeight、scrollWidth
scroll:滚动对象 offset:相对于版面或上层控件的位置 client:对象自身
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
clientHeight:是一个dom属性,表示元素的可见高度。计算公式:内容区域 + padding(top + bottom)-----------注意:不包括边框,和滚动条
clientTop:是一个只读的属性,表示元素的上边框的宽度,单位为像素,通常在计算元素的可视区域时候考虑一下,但是一般边框很小无需考虑。
clientLeft:表示左边框的宽度,clientTop表示上边框的宽度,但是没有clientRight,clientBottom
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
offsetheight:是一个dom属性,表示元素的高度。计算公式:内容区域 + 内边距(top + bottom) + 边框 ----------注意:包含边框
offsetTop:是一个只读属性,表示当前元素的上边框相对于父亲的顶部边缘的距离,也就是上边距。
offsetLeft:是一个只读属性,表示当前元素的左边框到父亲的左边缘的间距,也就是左边距。
offsetParent:是一个 DOM 元素的属性,用于获取元素的最近的定位父元素。该定位父元素是具有position
属性值为relative
、absolute
或fixed
的元素。如果没有这样的父元素,则返回null。
offsetWidth:是一个DOM元素的属性,获取元素的布局宽度。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
scrollHeight:是一个dom属性,表示元素的完整高度,计算公式:内容区域 + 内边距 + 溢出部分----------注意:也不包括边框,在没有滚动条时候和clientHeight一样。
scrollWidth:返回一个元素的内容宽度,表示元素完整的宽度,计算公式同上。
scrrollLeft:返回一个元素的水平滚动位置,即元素内容向左滚动的位置,如果没有横向滚动条他的值就是为0。
scrollTop:返回元素垂直滚动的位置,即元素向上滚动的像素值。如果没有纵向滚动条,则值为0。
2.常用方法
(1)getBoundingClientRect:是DOM元素的一个方法,返回一个DOMRect对象,包含元素的大小及其相对于视口的位置。
兼容性:IE5以上的版本。
返回的坐标是相对于视口的,因此在页面滚动时,值会变化。他包含以下属性:
top
: 元素上边框到视口顶部的距离,如果元素滚动顶部边框超过顶部,则为负值。right
: 元素右边框相对于视口左侧的距离,如果元素滚动底部边框超过顶部,则为负值。 ////////////////注意:top和bottom都是相对于可视区域顶部来计算的bottom
: 元素底边框相对于视口顶部的距离。left
:元素左边框相对于视口左侧的距离。width
: 内容的宽度,包含padding和border。height
: 内容的高度,,同上。
注意:这里的视口原点通常是浏览器页面的左上角,left就是dom的左边框相对于浏览器左边缘部分的距离,Top是距离浏览器顶部的距离。
方式1:倘若判断一个元素在不在可视区域内
1 2 3 4 5 6 7 8 9 | function isElementInViewport(el) { const rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && //////////浏览器窗口的高度和宽度的获取采用了兼容性处理 rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } |
上面的代码默认可视区域为整个浏览器(减去控制台的高度),然而通常我们的滚动区域只是页面中的一小块,这时候需要优化一下代码,如下:
1 2 3 4 5 6 7 8 9 10 11 | function isElementInScrollableArea(el, scrollableArea) { const rect = el.getBoundingClientRect(); const scrollableRect = scrollableArea.getBoundingClientRect(); return ( rect.top >= scrollableRect.top && rect.left >= scrollableRect.left && rect.bottom <= scrollableRect.bottom && rect.right <= scrollableRect.right ); } |
通常情况下:在数据懒加载的时候我们遇到的都是纵向滚动区域,也就是不需要关注左右距离,并且滚动区域的高度也是固定的,因此只需要关注上下即可,左右的判断可以省略。
具有如下的缺点:
a.重新渲染页面:当同时获取多个元素的属性时,浏览器需要重新渲染页面。getBoundingClientRect()方法会获取元素的宽、高、左、右等属性,这些属性的获取需要浏览器重新渲染整个页面,从而影响性能。
b.计算位置不精确:getBoundingClientRect()方法计算的是元素到窗口边界的距离,而不是屏幕中实际可见的位置。如果计算的位置信息不精确,可能会导致性能损失。
方式:2:通过元素的位置信息和滚动条滚动的高度
首先了解一下这个图的意义。
1 2 3 4 5 6 7 8 | function isInViewPort(element) { // 获取可视窗口的高度。 const scrollHeight= window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; // 获取滚动条滚动的高度 const scrollTop = document.documentElement.scrollTop; // 获取元素偏移的高度。就是距离可视窗口的偏移量。 const offsetTop = element.offsetTop; return offsetTop - scrollTop <= scrollHeight;<br> } |
此外:getBoundingClientRect
并不能满足所有情况,甚至说,它只能满足一种情况的判断,那就是需要判断的那个dom节点,它只身处在一个滚动条的情况下。什么意思呢,就是它所有的祖先节点,加起来的滚动条只有1个,如果它父节点有滚动条,父父节点也有滚动条,那这种方法就不好用了。
方式3:Intersection Observer
Intersection Observer
是一个现代的Web API,用于异步观察目标元素与祖先元素或视口的交叉状态。它可以帮助你判断元素是否在可视区域内,从而实现惰性加载、无限滚动等功能。举例使用步骤如下:
// 1. 创建 IntersectionObserver 实例 const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { // 2. 处理回调 if (entry.isIntersecting) { console.log('元素进入可视区域'); } else { console.log('元素离开可视区域'); } }); }, { root: null, // 默认视口 rootMargin: '0px', // 无额外边距 threshold: 0.5 // 50%可见时触发 }); // 3. 观察目标元素 const targetElement = document.querySelector('#target'); observer.observe(targetElement); // 4. 停止观察(可选) // observer.unobserve(targetElement); // observer.disconnect();
参数解释:
-
root:参考元素,默认为视口---------如果,你将
root
设置为null
,那么观察者将使用浏览器的视口(viewport)作为根元素。这意味着目标元素的可见性将相对于浏览器窗口来判断。 -
rootMargin:参考元素的边距,扩展或缩小交叉区域。
-
threshold:触发回调的可见比例阈值,可以是单个值或数组。
你在第三步骤可以通过滚动事件或者点击事件建立了observe连接之后,后面将会自动检测目标元素是否离开和进入可视区域,类似于eventbus这种。
(2)scrollIntoview:
本文来自博客园,作者:122www,转载请注明原文链接:https://www.cnblogs.com/131362wsc/p/17108726.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通