只要给table设置width(style或本身的width属性),不管设置padding和border是多少,offsetWidth都等于width的值。 经测量offsetWidth是没错的,那就是说是table的width设置的问题。 w3c的table部分中说width属性是the desired width of the entire table,我估计entire就是包含了padding和border,找不到什么其他说明,先这么理解吧。 定位方面,除了不支持fixed的ie6用absolute,其他都使用fixed定位。
table的border属性用来指定边框宽度,table特有的frame属性是用来设置或获取表格周围的边框显示的方式。 w3c的tabel的frame部分说明frame可以是以下值: void: No sides. This is the default value. above: The top side only. below: The bottom side only. hsides: The top and bottom sides only. vsides: The right and left sides only. lhs: The left-hand side only. rhs: The right-hand side only. box: All four sides. border: All four sides. 这些值指明了要显示的边框。要留意的是虽然说void是默认值,但不设置的话其实是一个空值,这时四条边框都会显示。 还有frame对style设置的border没有效果,测试下面代码:
上面用到了parentNode,这里顺便说说它跟offsetParent,parentElement的区别。 先看看parentNode在w3c的说明: The parent of this node. All nodes, except Document, DocumentFragment, and Attr may have a parent. However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is null. 很简单,就是节点的父节点,看过dom都知道。
再看看比较容易区分的offsetParent,它在mozilla和msdn都说得比较模糊,在w3c就比较清楚了: The offsetParent attribute, when called on element A, must return the element determined by the following algorithm: 1,If any of the following holds true return null and stop this algorithm: A is the root element. A is the HTML body element. The computed value of the position property for element A is fixed. 2,If A is an area HTML element which has a map HTML element somewhere in the ancestor chain return the nearest ancestor map HTML element and stop this algorithm. 3,Return the nearest ancestor element of A for which at least one of the following is true and stop this algorithm if such an ancestor is found: The computed value of the position property is not static. It is the HTML body element. The computed value of the position property of A is static and the ancestor is one of the following HTML elements: td, th, or table. 4,Return null. 这里主要有四点: 1,如果是根元素、body元素或元素的position是fixed,将返回null; 2,如果是area元素,会返回最接近的map元素; 3,返回至少符合以下一个条件的最接近该节点的元素:1,元素的position不是static;2,是body元素;3,源元素的position是static,祖先元素中的以下元素:td,th或table。 4,返回null。 其中第三点是最常见的情况,详细可以看下面的测试:
//获取原table位置 var o = this._oTable, iLeft = o.offsetLeft, iTop = o.offsetTop; while (o.offsetParent) { o = o.offsetParent; iLeft += o.offsetLeft; iTop += o.offsetTop; } this._oTableLeft = iLeft; this._oTableTop = iTop; this._oTableBottom = iTop + this._oTableHeight; //获取原tr位置 o = this._oRow; iTop = o.offsetTop; while (o.offsetParent) { o = o.offsetParent; iTop += o.offsetTop; } this._oRowTop = iTop; this._oRowBottom = iTop + this._oRow.offsetHeight;
不过这里介绍一个更好的方法,通过getBoundingClientRect方法来获取。 在mozilla是这么说明的: The returned value is a TextRectangle object, which contains read-only left, top, right and bottom properties describing the border-box, in pixels, with the top-left relative to the top-left of the viewport... 返回一个TextRectangle对象,包含left, top, right和bottom几个只读属性,以px为单位来表示边界框相对视窗左上角的位置。(偶英文烂啊) 注意是相对视窗,不是文档哦,如果要相对文档还必须加上scrollLeft/scrollTop。 通过下面的测试可以看到两个方法返回的结果都是相同的:
点击运行可以看到效果: [Ctrl+A 全选 提示:你可先修改部分代码,再按运行]
程序中如果支持getBoundingClientRect就会用它来获取位置参数:
复制代码 代码如下:
//用getBoundingClientRect获取原table位置 var top = this._doc.scrollTop, rect = this._oTable.getBoundingClientRect(); this._oTableLeft = rect.left + this._doc.scrollLeft; this._oTableTop = rect.top + top; this._oTableBottom = rect.bottom + top; //获取原tr位置 rect = this._oRow.getBoundingClientRect(); this._oRowTop = rect.top + top; this._oRowBottom = rect.bottom + top;
var top =this._doc.scrollTop, left =this._doc.scrollLeft ,outViewTop =this._oRowTop < top, outViewBottom =this._oRowBottom > top +this._viewHeight; if(outViewTop || outViewBottom){}