为什么表格单元格的Javascript宽度一个像素太短?

当你应用border-collapse: collapse; 到一个表“将”它的单元边界“融合”在一起,它开始在确定Javascript中表格单元格的宽度时出现问题。 例如,看看这个页面:
http://game-point.net/misc/browserTests/scratchpads/jsTableWidth/
有两个表,一个带有折叠边框,另一个没有。 如果你单击没有折叠边框的行中的一行,jQuery的innerWidth和outerWidth函数会报告我期望看到的内容(内容宽度,内容加上边框宽度;没有填充)。

但是,如果单击带有折叠边框的表中的行,则会出现浏览器不一致的行为,尤其是在clientWidth属性上。 在Firefox中, clientWidthwidth()相同。 在IE和Chrome中,它高出1个像素,在Opera中,它与width()相同,但Opera的width()太小。 事实上,除了Firefox之外,我测试的所有浏览器中的width()都是一个太小的像素。 因此,如果您截取屏幕截图并且内容实际为80px,则width()为79px(jQuery从计算的CSS值中获取)。 为什么是这样?

我想要获得实际内容的宽度。 我似乎无法使用width()因为只有Firefox才能使用折叠边框。 我不能使用outerWidth()因为它包括边框(或者可能只是一个边框,因为它只比实际内容宽度大1px)。 我不能使用clientWidth因为它的值在浏览器之间是不一致的。 当边框折叠时,我应该怎么做以及为什么在大多数浏览器中width() 1px太短?

在折叠边界模型中,单元格不仅仅是“融合”,而是由相邻单元共享

所以说你有这样的标记:

 

在折叠边框模型中,此表的宽度为102px。 有0.5px的边界实际上桌子之外 ,然后0.5px的边界,然后100px的单元格,然后1px的边框,然后100px的单元格,然后0.5px的边框,然后0.5px的边框在桌子外面。 请参见http://www.w3.org/TR/CSS21/tables.html#collapsing-borders上的图片

那么,鉴于UA应该为第一个细胞的不同宽度返回什么? 它应该是100px吗? 101px? 102px? 别的什么? 简单地返回内容宽度加上边框宽度将返回102px,但单元占用的实际空间仅为101px …

此外,如果jQuery正在计算内容宽度本身,它也会遇到这个问题,如果它不是特殊情况下边框折叠的单元格。

而且没有真正的clientWidth规范,更不用说jQuery的width()等了。 这就解释了为什么你看到的结果到处都是。

至于你应该做什么,如果你真的确切地知道你的边界发生了什么,你应该可以得到BroadingClientRect()。width(假设浏览器不会弄乱 )并减去边框的半宽。 如果您需要使用各种不同的边框宽度,我不确定是否有一个很好的解决方案。

我认为每个浏览器中的问题,但Opera实际上是jQuery用width()函数做的事情; 它有宽度和高度的自定义钩子,它并不总是返回真正的计算宽度。 当我使用window.getComputedStyle来获取这些表格单元格的宽度时,它确实给了我正确的渲染宽度。 我将把Opera的window.getComputedStyle输出报告为一个bug,因为即使绕过jQuery,它似乎也没有给你正确的渲染宽度。