有没有办法检测浏览器是不是具有亚像素精度?
Posted
技术标签:
【中文标题】有没有办法检测浏览器是不是具有亚像素精度?【英文标题】:Is there a way to detect if the browser has subpixel precision?有没有办法检测浏览器是否具有亚像素精度? 【发布时间】:2012-09-18 06:10:53 【问题描述】:有没有办法检测浏览器是否对元素具有亚像素精度?
IE9 与其他任何主流浏览器不同,它的元素具有亚像素精度(元素宽度可以是 50.25 像素),因此,我需要区别对待。
一种方法是使用 jQuery 检测浏览器名称和版本,但这在 jQuery 中已弃用且不推荐,而是建议应针对浏览器名称和版本测试功能的存在。
【问题讨论】:
赞成并加注星标,因为我根本不知道亚像素如何工作。 你不能把一个div的样式设置成“50.5px”,然后在javascript中检查它的宽度,onload,看看它是否被四舍五入? 有趣的是,据我所知,IE 是实现亚像素精度的主流浏览器中最后一个的(或者我们在谈论两个不同的东西;))。 @Yoshi 也许是为了别的,但是对于元素的尺寸,所有其他主流浏览器都有整数值。 $Yoshi getComputedStyle 不是指 CSS 值吗?无论如何,我认为这是一个更复杂的问题,考虑到浏览器内部查看值的方式、您对显示的观点、josh 下面提到的规范以及用户看到的实际显示尺寸。我想还有更多需要了解和搜索的内容。然而,事实仍然是,IE9 处理它的方式有所不同,但要正确理解它,还有更多需要搜索的内容。 【参考方案1】:您可以创建一个奇数大小的容器并将两个 50% 宽度的元素放入其中,然后查看它们是否已按 50:50 拆分。
见http://jsfiddle.net/alnitak/jzrQ6/
它在 MacOS X 10.8.2 上的 Chrome 22.0.1229.79 上返回 false
,在 Firefox 15.0.1 上返回 true
。我没有 MSIE 来测试它。
【讨论】:
我在 Firefox 和 IE10 中得到true
。
Chrome 22.0.1229.79 m 在 Win 7 上
在 Chrome 中,我在 50% 到 149% 之间的缩放级别上得到错误,而在该范围之外的许多(但不是全部)缩放级别上是正确的。
@josh3736 有趣的发现!
jsfiddle.net/KAW3d/1 - 在 IE6 和 IE7 中 100.5px + 100.5px = 200px(两个 100.5px 浮点数适合 200px 容器),在 IE8+ 中 100.5px + 100.5px > 200px【参考方案2】:
我不知道你从哪里知道 IE9 是唯一支持小数像素单位的浏览器,但这种假设是完全错误的。
来自section 4.3 of the spec(已添加重点):
长度值的格式(在本规范中用
表示)是一个 (带或不带小数点)紧跟一个单位标识符(例如,px、em 等)。
并定义
某些值类型可能具有整数值(由
表示)或实数值(由 表示)。实数和整数仅以十进制表示法指定。 由一个或多个数字“0”到“9”组成。 可以是 ,也可以是零个或多个数字,后跟一个点 (.),后跟一个或多个数字。整数和实数前面都可以用“-”或“+”表示符号。 -0 等价于 0,不是负数。
因此,根据规范,px
长度单位必须支持小数。
为了证明这一点,请查看fullscreen 中的this fiddle 并使用浏览器的缩放功能一直放大:
在这个 Chrome 屏幕截图中,请注意 5.5px 的蓝色框确实比 5px 的红色框要高。
我认为混淆可能源于以下事实:非标准 element.clientHeight
返回计算的(四舍五入)整数值,并且舍入在不同情况下的发生方式不同浏览器。
在我的小提琴中,对于蓝色 <div>
的 clientHeight
,IE9 和 Firefox 15 在 100% 缩放时给出 6
。 Chrome 22 和 Opera 12 提供5
。在所有浏览器中,该属性的值都会随着用户更改浏览器的缩放级别而变化。
换句话说,它是不可靠的。
如果您想使用元素的实际分数单位进行计算,请使用getComputedStyle
。
var el = $('#b')[0]; // the actual DOM element
var height = parseFloat(getComputedStyle(el).height); // => 5.5
【讨论】:
我与 Yoshi 进行了更长的讨论,但在您的示例中,如果您使用开发人员工具查看 Properties - htmlDivElement - clientWidth 中元素的客户端设置,它将显示整数值。你知道这是为什么吗?clientWidth
/clientHeight
是非标准属性,在所有浏览器中总是返回整数(换句话说,舍入)值。在updated fiddle 中,请注意clientHeight
的值会随着您更改浏览器的缩放级别而波动。
问题的核心是 IE9 和其他浏览器处理显示的方式之间的差异,特别是在我的情况下,相同的布局在 IE9 中的显示与其他浏览器不同,我认为这是一个问题IE9处理亚像素精度的方式。从您的帖子以及与 Yoshi 的讨论中,我了解到这个问题还有更多内容需要搜索,并了解每个浏览器处理此问题的方式之间的差异。您的帖子非常有用,有助于得出这个结论,您的解决方案也很有帮助。【参考方案3】:
http://jsfiddle.net/KAW3d/1/
在 IE6、IE7 和 Opera 12.02 中:100.5px + 100.5px = 200px(两个 100.5px 的浮点数适合 200px 的容器) 在 IE8+、Firefox 15.0.1、Chrome 22 中:100.5px + 100.5px > 200px【讨论】:
【参考方案4】:最近我们不得不进行一些严格的像素完美计算,我需要检查浏览器是否会支持亚像素布局。我使用其他一些答案作为指南创建了一个用于Conditionizr 或Modernizr 的测试:
conditionizr.add('subpixel-layout', function()
var $testWrap = $(
'<div style="width: 4px; height: 2px; position: absolute; right: 0; bottom: 0;">' +
'<div id="subpixel-layout-1" style="width: 2.5px; height: 1px; float: left;"></div>' +
'<div id="subpixel-layout-2" style="width: 2.5px; height: 1px; float: left;"></div>' +
'</div>'
).appendTo('body');
var supported = $('#subpixel-layout-1').position().top !== $('#subpixel-layout-2').position().top;
$testWrap.remove();
return supported;
);
然后你可以使用:
conditionizr.on('!subpixel-layout', function ()
// subpixel layout is NOT available
);
你应该可以在 Modernizr 中使用 Modernizr.addTest()
做同样的事情,但我没有测试它。
显然我在这里使用jQuery
,但如果没有它也应该很简单。
【讨论】:
以上是关于有没有办法检测浏览器是不是具有亚像素精度?的主要内容,如果未能解决你的问题,请参考以下文章
Qt + opencv 角点检测(Shi-Tomas + 亚像素精度角点)