/**
* 文档坐标
* 视口坐标
* 鼠标坐标
*
* 元素位置和尺寸
*/
function xx() {
// 最大可滚动的大小 = 可滚动的大小 - 可视区域的大小
var scrollMax = d1.scrollHeight - d1.clientHeight;
// 如果最大可滚动的大小 - 已滚动的大小 >= 阀值
if (scrollMax - d1.scrollTop >= threshold ) {
// 开始请求ajax
}
// 偏移大小 包含边框大小 内边距大小 + 实际内容可视区域高度(如果有滚动条,包含滚动条大小)
// d1.offsetHeight
}
// 获取窗口的滚动条偏移量
function getScrollOffsets(w) {
w = w || window;
// 对所有现代浏览器有效,除了ie<=8的浏览器
if (w.pageXOffset != null) {
return {
x: w.pageXOffset,
y: w.pageYOffset
}
}
// 对所有在标准模式下的浏览器
var d = w.document;
if (d.compatMode === 'CSS1Compat') {
return {
x: d.documentElement.scrollLeft,
y: d.documentElement.scrollTop
}
}
// 如果处于怪异模式
return {
x: d.body.scrollLeft,
y: d.body.scrollTop
}
}
// 获取视口尺寸
function getViewportSize(w) {
w = w || window;
if (w.innerWidth != null) {
return {
w: w.innerWidth,
h: w.innerHeight
}
}
var d = w.document;
if (d.compatMode === 'CSS1Compat') {
return {
w: d.documentElement.clientWidth,
h: d.documentElement.clientHeight
}
}
return {
w: d.body.clientWidth,
h: d.body.clientHeight
}
}
// 返回一个元素在**视口(viewport)坐标系**中的坐标以及该元素的尺寸(ie没有包含元素的尺寸)
// dom.getBoundingClientRect() // {left: , top, width, height}
// 包含padding和border,但不包含margin
function getBCR(dom) {
var bcr = dom.getBoundingClientRect();
bcr.width = bcr.width || (bcr.right - bcr.left);
bcr.height = bcr.height || (bcr.bottom - bcr.top);
return bcr;
}
// offsetWidth offsetHeight
// 只读的
// 单位是px
// 包括border和padding,但包括margin
// offsetLeft offsetRight
// 对已定位元素的子孙或者table cell,返回的坐标相对于祖先,如果offsetParent为null,则相对于document
// 计算一个元素在**文档坐标系**中的坐标
function getElementPosition(e) {
var x = 0, y = 0;
while (e != null) {
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return {
left: x,
top: y
}
}
// offsetWidth包含border、content area、padding
// clientWidth跟offsetWidth的区别是前者不包含border,只有content area和 padding
// 如果有滚动条,clientWidth不包含滚动条的宽度,类似的clientHeight不包含滚动条的高度
// 在内联元素中clientWidth和clientHeight总是为0
// 标准模式下document.documentElement或者怪异模式下document.body,当没有垂直滚动条的时候调用 clientWidth跟 window.innerWidth返回的值是一致的,clientHeight和 window.innerHeight亦如此
// window.innerWidth,在有滚动条出现的情况下,默认已经包含了滚动条的宽度而document.documentElement.clientWidth是不包含滚动条宽度的
// 若果滚动条在左边或者上面的位置,那么clientLeft或clientTop包含滚动条的宽度或者高度
// scrollWidth和scrollHeight包含元素的content以及padding还有溢出(overflowing)的content
// scrollLeft和scrollTop是可读以及可写的
// 因为HTML elements没有scrollTo,素以你可以设置scrollLeft或scrollTop来达到同样的目的
// 当文档包含可滚动的元素的时候(when a document contains scrollable elements with overflowing content),上面的getElementPosition有缺陷
// 原因是之前定义的getElementPosition函数没有考虑到scrollbar position(it does not take scrollbar position into account)
// 修改如下,修改后的版本返回的值跟 getBoundingClientRect()一致(实践证明还是有些许的偏差)
// 经过修复后,getElementPosition2返回的是视口坐标系中的坐标,如果要转换成为文档坐标系中的坐标则需要加上getViewportSize()返回的left和top
function getElementPosition2(elt) {
var x = 0, y = 0;
// 循环累加 offsets
for (var e = elt; e != null; e = e.offsetParent) {
x += e.offsetLeft;
y += e.offsetTop;
}
// 所有祖先元素
for (var e = elt.parentNode; e != null && e.nodeType == 1; e = e.parentNode) {
x -= e.scrollLeft;
y -= e.scrollTop;
}
return {
left: x,
top: y
}
}
/**
* jQuery offset() 返回的是文档坐标系中的坐标 如果要转换为 视口坐标系中的坐标可以加上$(window|document).scrollTop() 和 $(window|document).scrollLeft()
*
*/
// 翻译不好的书籍诟病:修饰(比如定于从句)信息丢失,术语解释别扭,翻译错误
// 纠正位于(0, 0)处元素的位置,ie会返回(2, 2),其他浏览器会返回(0, 0)
function getBoundingClientRect(element) {
if (element.getBoundingClientRect) {
// 先判断函数上是否有offset,这个属性作为临时缓存数据的地方来使用
if (typeof arguments.callee.offset != 'number') {
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
// 创建临时的html元素
var temp = document.createElement('div');
temp.style.cssText = 'position: absolute; left: 0; top: 0'; //定位元素的位置到视口坐标系中的(0, 0)处
document.body.appendChild(temp);
var offset = -temp.getBoundingClientRect().top - scrollTop;
// 保存临时变量于函数上
arguments.callee.offset = offset;
// 销毁临时的html元素
document.body.removeChild(temp);
temp = null;
}
var rect = element.getBoundingClientRect();
var offset = arguments.callee.offset;
return {
left: rect.left + offset,
right: rect.right + offset,
top: rect.top + offset,
bottom: rect.bottom + offset
}
} else {
var offset = getElementPosition2(element); // 获取视口坐标系中的元素坐标
var left = offset.left;
var top = offset.top;
return {
left: left - scrollLeft,
top: top - scrollTop,
right: left - scrollLeft + element.offsetWidth,
bottom: top - scrollLeft + element.offsetHeight
}
}
}