关于JQ offset()top 获取位置不准确的解决方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于JQ offset()top 获取位置不准确的解决方法相关的知识,希望对你有一定的参考价值。
参考技术A 应用场景:网站响应式开发问题重现:刷新获取距离顶部偏移位置不准确,偶尔有准确。
问题解决思路:刚开始以为是绝对定位的问题,脱离文档流,所以位置获取不到,后来发现是渲染问题,图片没加载完成的时候不占位置,所以位置获取不到
问题解决:使用load,当页面加载完成后,再获取位置,使用document(ready)并不能保证页面全部渲染完毕
后来发现使用load的时候报错,原因是因为最高版本的JQ没有load方法,最后解决方案是使用on监听
各种位置和高度计算:.position().offset().outerHeight().scrollTop.scrollHeight.clientHeight
1、.position()和.offset()
jquery的.position()获取相对于最近的position为relative或absolute的父元素的偏移,返回.position().left和.position().top,不算上自己的margin-left;
jquery的.offset()获取相对于视口左上角的偏移,返回.offset().left和.offset().top, 算上自己的margin-left,,还可以设置.offset({left:,top:});这个很有用,比如编写日期控件时,append到body上,然后就可以根据input的.offset()和高度设置日期控件的.offset(),最终这些值自动会被换算为position为relative(相对于body)的top和left。
jquery的.offset()与js的obj.offsetLeft和.obj.offsetTop一样,只是这个不能赋值。
2、.outerHeight()、.innerHeight()和.height()
jquery的.outerHeight()=border+padding+height,等同于js的.offsetHeight(.offsetWidth同理)
.outerHeight(true)=margin+border+padding+height
.innerHeight()=padding+height
.height()设置和获取高度
3、.scrollTop和.scrollHeight
.scrollTop:已经滚动过的高度;
.scrollHeight:整个滚动的高度,从开始到滚动结束滚动过的高度,包括滚动元素自身的高度。
用图来解释:如下图,contentContainer为父元素,content为它的子元素,由于它的高度设置得比父元素高度高,所以父元素出现了滚动条。
假设现在滑动条已划过了一段距离,
则contentContainer的scrollTop为a,scrollHeight为b。
4、监听整个网页的滚动事件:
测试ie11、chorme、firefox,发现body上不支持监听整个网页的滚动事件scroll,window上都支持:window.onscroll=function(){};
5、获取/设置网页已滚动的高度:
chrome |
document.documentElement.scrollTop无效为0, document.body.scrollTop有效与$(\'body\').scrollTop()+\',\'+$(document).scrollTop()等值 |
safari与chrome表现相同 | |
ie11(包括其模拟的IE10-7) |
document.documentElement.scrollTop有效与$(document).scrollTop()等值, document.body.scrollTop无效为0,$(\'body\').scrollTop()无效为0 |
firefox |
document.documentElement.scrollTop有效与$(document).scrollTop()等值, document.body.scrollTop无效为0,$(\'body\').scrollTop()无效为0 |
所以获取网页已滚动的高度时:Math.max(document.documentElement.scrollTop,document.body.scrollTop)或$(document).scrollTop()
jquery和js的scrollTop都可以赋值。
所以如果要设置‘返回顶部’的效果应该:
$(\'#totop\').click(function(){ document.body.scrollTop?document.body.scrollTop=0:document.documentElement.scrollTop=0; //或$(document).scrollTop(0); })
另外测试同一个页面,用鼠标滚轮把页面滚动到底,ie11和chrome都只触发了两次,大概是scrollTop从166到230,而firefox则触发了15次,看来ie11和chrome对触发滚动事件做了优化。可以手动添加判断两次滚动间隔超过多少px才允许运行onscroll函数:
var stop=Math.max(document.documentElement.scrollTop,document.body.scrollTop); window.onscroll=function(){ if(Math.max(document.documentElement.scrollTop,document.body.scrollTop)-stop>100) {//do something} }
6、获取body视口高度:
有<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">时:
chrome |
document.documentElement.clientHeight有效,window.innerHeigh有效, document.body.clientHeight无效与$(\'body\').height()等值 |
ie11(包括其模拟的IE10-9) |
document.documentElement.clientHeight有效,window.innerHeigh有效, document.body.clientHeight无效与$(\'body\').height()等值, |
用ie11模拟ie8、ie7 | window.innerHeight为undefined,其他相同 |
firefox |
document.documentElement.clientHeight有效,window.innerHeigh有效, document.body.clientHeight无效与$(\'body\').height()等值 |
无<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">时:
chrome:document.documentElement.clientHeight无效与$(\'body\').outerHeight(true)等值,window.innerHeigh有效,document.body.clientHeight有效,即使是有<!DOCTYPE>也是如此。
ie11:document.documentElement.clientHeight有效,document.body.clientHeight有效(ie7,8,9:无效与$(\'body\').outerHeight(true)等值),window.innerHeigh有效,(用ie11模拟ie8、ie7时,window.innerHeight为undefined),即使是有<!DOCTYPE>也是如此。
所以在保证有完整<!DOCTYPE...声明的前提下,获取body的视口高度为:document.documentElement.clientHeight;
7、判断div的滚动条滚到底部
只要判断这个div已滚动的距离scrollTop+自己本身的高度offsetHeight>这个div的scrollHeight就表示滚动到底了。
如:一个id=\'contentContainer\'的div里面包含一个高度查过自己 id=\'content\'的子div。
则只要
document.getElementById(\'contentContainer\').onscroll=function(){ if(this.scrollTop+this.offsetHeight>=this.scrollHeight){ $(this).append(\'bottom\'); //不要用==因为很多浏览器并不是每滚动1px就触发scroll事件的 } }
8、判断body的滚动条滚到底部:
获取页面的scrollHeight:document.documentElement.scrollHeight在各浏览器中表现一致。
监听页面滚动条滚到底部:
window.onscroll=function(){ var scrolltop=Math.max(document.documentElement.scrollTop,document.body.scrollTop); if(scrolltop+document.documentElement.clientHeight>=document.documentElement.scrollHeight) alert( \'nowbottom\' ); };
以上是关于关于JQ offset()top 获取位置不准确的解决方法的主要内容,如果未能解决你的问题,请参考以下文章
JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离
js和jq中常见的各种位置距离之offset和offset()的区别