这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
现在网上最流行方法是 John Resig 在《Pro JavaScript techniques》提出的 offset 大法,累加元素 offsetParent 的 offsetLeft 和 offsetTop 一直到 DOM 的顶层。
- //取得元素x坐标
- function pageX(elem) {
- return elem.offsetParent ? (elem.offsetLeft + pageX(elem.offsetParent)) : elem.offsetLeft;
- }
- //取得元素y坐标
- function pageY(elem) {
- return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
- }
貌似这位大神在出这本书时比较赶,有许多纰漏,最后大神也发觉这两个函数有问题,并没有把它们运用到 JQuery 中。由于是用累加的方式去计算,只要一个元素出现问题,就有可能层层被大,因此我在精确获取样式属性时就摒弃这种方法。主要误算参照
大神的结论:
Handling table border offsets.
Fixed positioned elements.
Scroll offsets within another element.
Borders of overflowed parent elements.
Miscalculation of absolutely positioned elements.
随着新锐浏览器都支持 IE 的 getBoundingClientRect 方法,我们得以用更简单更快捷更安全的方法来定位页面元素。getBoundingClientRect 返回的是一个集合,分别为元素在浏览器可视区的四个角的坐标。
不过它在 IE 的标准模式存在一个奇怪的问题,html 元素是有 border 的,默认是2px,并且是不可修改的;怪癖模式是没有的。详见 http://msdn.microsoft.com/en-us/library/ms536433(VS.85).aspx
This method retrieves an object that exposes the left, top, right, and bottom coordinates of the union of rectangles relative to the client's upper-left corner. In Microsoft Internet Explorer 5, the window's upper-left is at 2,2 (pixels) with respect to the true client.
我们做一些测试(请分别在 IE6 与 IE8 中进行):
1、标准模式,没有重设 html 的 border
[Ctrl+A 全选 注: 如需引入外部 Js 需刷新才能执行]
- <!doctype html>
- <html dir="ltr" lang="zh-CN">
- <head>
- <meta charset="gb2312" />
- <meta http-equiv="X-UA-Compatible" content="IE=8">
- <style type="text/CSS">
- html, body{ /* border: 0; */ }
- </style>
- <script type="text/javascript">
- var isQuirk = (document.documentMode) ? (document.documentMode == 5) ? true: false: ((document.compatMode == "CSS1Compat") ? false: true);
- var getCoords = function(el) {
- var box = el.getBoundingClientRect(),
- top = box.top,
- left = box.left
- return {
- top: top,
- left: left
- };
- };
- var text = function() {
- var r = getCoords(document.documentElement) alert(r.top + "," + r.left);
- alert(document.documentElement.clientLeft) if (isQuirk) {
- alert("怪癖模式");
- } else {
- alert("标准模式");
- }
- }
- </script>
- <title>
- getBoundingClientRect
- </title>
- </head>
- <body>
- <p>
- <button type="button" onclick="text()">
- 运行代码
- </button>
- </p>
- </body>
- </html>
2、标准模式,重设 html 的 border
[Ctrl+A 全选 注: 如需引入外部 Js 需刷新才能执行]
- <!doctype html>
- <html dir="ltr" lang="zh-CN">
- <head>
- <meta charset="gb2312" />
- <meta http-equiv="X-UA-Compatible" content="IE=8">
- <style type="text/css">
- html, body{ border: 0; }
- </style>
- <script type="text/javascript">
- var isQuirk = (document.documentMode) ? (document.documentMode == 5) ? true: false: ((document.compatMode == "CSS1Compat") ? false: true);
- var getCoords = function(el) {
- var box = el.getBoundingClientRect(),
- top = box.top,
- left = box.left
- return {
- top: top,
- left: left
- };
- };
- var text = function() {
- var r = getCoords(document.documentElement) alert(r.top + "," + r.left);
- alert(document.documentElement.clientLeft) if (isQuirk) {
- alert("怪癖模式");
- } else {
- alert("标准模式");
- }
- }
- </script>
- <title>
- getBoundingClientRect
- </title>
- </head>
- <body>
- <p>
- <button type="button" onclick="text()">
- 运行代码
- </button>
- </p>
- </body>
- </html>
3、怪癖模式,没有重设 html 的 border
[Ctrl+A 全选 注: 如需引入外部 Js 需刷新才能执行]
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <style type="text/css">
- html, body{ /* border: 0; */ }
- </style>
- <script type="text/javascript">
- var isQuirk = (document.documentMode) ? (document.documentMode == 5) ? true: false: ((document.compatMode == "CSS1Compat") ? false: true);
- var getCoords = function(el) {
- var box = el.getBoundingClientRect(),
- top = box.top,
- left = box.left
- return {
- top: top,
- left: left
- };
- };
- var text = function() {
- var r = getCoords(document.documentElement) alert(r.top + "," + r.left);
- alert(document.documentElement.clientLeft) if (isQuirk) {
- alert("怪癖模式");
- } else {
- alert("标准模式");
- }
- }
- </script>
- <title>
- getBoundingClientRect
- </title>
- </head>
- <body>
- <p>
- <button type="button" onclick="text()">
- 运行代码
- </button>
- </p>
- </body>
- </html>
4、怪癖模式,重设 html 的 border
[Ctrl+A 全选 注: 如需引入外部 Js 需刷新才能执行]
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <style type="text/css">
- html, body{ border: 0; }
- </style>
- <script type="text/javascript">
- var isQuirk = document.documentMode ? document.documentMode == 5 : document.compatMode && document.compatMode != "CSS1Compat";
- var getCoords = function(el) {
- var box = el.getBoundingClientRect(),
- top = box.top,
- left = box.left
- return {
- top: top,
- left: left
- };
- };
- var text = function() {
- var r = getCoords(document.documentElement) alert(r.top + "," + r.left);
- alert(document.documentElement.clientLeft) if (isQuirk) {
- alert("怪癖模式");
- } else {
- alert("标准模式");
- }
- }
- </script>
- <title>
- getBoundingClientRect
- </title>
- </head>
- <body>
- <p>
- <button type="button" onclick="text()">
- 运行代码
- </button>
- </p>
- </body>
- </html>
John Resig 给出的方案就是用 clientTop,clientLeft 作减值。以下函数就是从 JQuery 中抠出来,就后就用它获取页面元素的坐标,比 offset 大法安全多了。
- var getCoords = function(el) {
- var box = el.getBoundingClientRect(),
- doc = el.ownerDocument,
- body = doc.body,
- html = doc.documentElement,
- clientTop = html.clientTop || body.clientTop || 0,
- clientLeft = html.clientLeft || body.clientLeft || 0,
- top = box.top + (self.pageYOffset || html.scrollTop || body.scrollTop) - clientTop,
- left = box.left + (self.pageXOffset || html.scrollLeft || body.scrollLeft) - clientLeft
- return {
- 'top': top,
- 'left': left
- };
- };
其中 self.pageYOffset 相当于 window.self.pageYOffset,是火狐的一个属性,相当于 document.body.scrollTop。以下是它的定义:
Definition: The pageYOffset property is used to determine the Y coordinate of the scroll position in some browsers. This is not a reserved word so you can declare your own variable or function called pageYOffset but if you do then you will not be able to find or alter the scroll position of a window in some browsers
来源: http://www.phperz.com/article/17/0716/285841.html