设为首页 加入收藏

TOP

JavaScript 获取元素的坐标详解
2017-07-13 10:22:58 】 浏览:386
Tags:JavaScript 获取 元素 坐标 详解

引言


  最近突然看到了有关图片懒加载的问题,大致意思就是初始状态下页面只加载浏览器可视区域的图片,剩余图片在当浏览器可视区域滚动到其位置时才开始加载。貌似现在许多大型网站都有实现懒加载,所以我便就此问题思考了一下。首先第一个问题是浏览器没有相关的 API 方法可以检测某个元素是否在可视区域,那么就只能我们人工计算,所以这里就涉及到了元素长宽,滚动条位置的知识。本文涉及的到的知识有元素长宽 clientWidth/offsetWidth/scrollWidth 的区别、以及 clientTop/offsetTop/scrollTop 的区别,并给了获取元素坐标的源代码。


  通常大家获取元素的长宽的时候都会使用一些框架封装好的方法,比如 jQuery.prototype.width() ,这些框架使用起来方便快捷,不过其中涉及到的知识还是非常多的,关于元素的长宽,有多种的获取方法,其代表的实际意义也是不同的。


  简单来说可以使用下列公式:


  clientWidth = width(可视区) + padding


  offsetWidth = width(可视区) + padding + border


  scrollWidth = width(内容区) 


  假设有我们以下一个元素:


   以上 DEMO 是常规情况下的区别,下面加上一个滚动条我们们再来观察以下:


  我们使用以下公式:


  clientTop = border


  offsetTop = 元素边框外围至父元素边框内围


  scrollTop = 元素可视区域顶部至实际内容区域的顶部


  给定以下两个元素 container 和 test


   有了以上知识基础之后,我们现在需要考虑的问题是,如何获取页面元素的绝对位置,也就是在文档流内容区的位置。我们知道,元素的 offsetTop 属性可以获取当前元素边框外围至父元素边框内围的的距离,clientTop 可以获取元素边框的宽度。那么现在用一个递归的公式就可以求得当前元素在页面中的绝对位置:


  Element.absoluteTop = Element.parent.absoluteTop + Element.offsetTop + Element.clientTop;


  同理,我们用参照元素的长宽减去 left 和 top 和定位,即可得到 right 和 bottom 的定位;


   所以我们可以编写以下工具来获取元素的绝对位置,也就是在内容区的定位(参照元素必须是目标元素的祖先元素):


  此方法可以获取一个元素相对于一个父元素的定位,如果要获取元素在整张页面,直接传入 document 即可:


  在上一小节中,我们封装了一个函数,这个函数可以用来获取一个元素的相对于一个祖先元素的绝对定位坐标,在这一小节中,我们来获取元素相对于浏览器窗口可视区域的定位坐标。在上一个函数中,我们可以获取一个元素在 document 当中的定位,还记得我们在第二小节中的 scrollTop 属性吗?该属性可以获取滚动窗口可视区域顶端距离内容区顶端的距离,我们用元素的绝对定位坐标减去 document 的滚动定位就是我们想要的浏览器窗口定位啦(相对于浏览器左上角):


  ViewportTop = Element.absoluteTop - document.body.scrollTop;


  这里需要注意一个兼容性的问题,在 Chrome 中可以用 document.body.scrollTop 和 window.pageYOffset,IE 7/8 只能通过 document.documentElement.scrollTop 获取, FireFox 和 IE9+ 可以用 document.documentElement.scrollTop 和 window.pageYOffset 获取,Safari 需要 window.pageYOffset 获取。所以这里我们需要做一下浏览器兼容:


  scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;


  我们在刚才的工具上添加一个方法:


  通过 Position.getViewport 方法可以获取元素相对于浏览器窗口的定位:


  在上面的几个方法中,我们可以获取元素的文档流定位和视窗定位,不过这还是不能判断一个元素是否在可视区域内,因为视窗定位可以是非常大的数字,这样元素就在视窗的后面。这里我们需要使用浏览器视窗高度 window.innerHeight 属性,在 IE8 以下需要用 document.documentElement.clientHeight 来获取。


  windowHeight = window.innerHeight || document.documentElement.clientHeight;


  现在,我们用窗口的高度,减去相对于浏览器窗口的定位,即可获取相对于浏览器窗口右下角的定位;


  现在我们使用 Position.getViewport(targetNode) 方法可以获取元素左上角相对于窗口4个方向的定位:


  有了这个方法,现在就可以真正的判断元素是否在可视区域内了:


  判断理由很简单,如果有一边的定位是负值,那么元素就不在视窗内。


 


   浏览器兼容性:


  IE7 也可以使用,不过结果可能会有一点差异。


  在文章的开始,我们提到过图片懒加载的问题,那么具体需要怎么实现呢?这里只是给出一个思路:


  初始状态下不设置 img 的 src,将图片的真实 url 缓存在 Img 标签上,我们可以设置为 data-src ,这样图片就不会加载了,随后给鼠标添加 mousescroll 事情,每次鼠标滚动的时候将进入可视区域的图片的 src 还原,这样也就实现了图片懒加载效果。不过初始状态下需要将页面可视区域的图片先加载出来。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java基础教程之this关键字的作用 下一篇JavaScript 逻辑运算符(与、或)..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目