css-在Javascript中将em转换为px(并获取默认字体大小)
在某些情况下,获取em测量的确切像素宽度可能会很有用。 例如,假设您有一个具有CSS属性(如border或padding)的元素(以ems为单位),并且您需要获取border或padding的确切像素宽度。 有一个涉及此主题的现有问题:
如何使用JavaScript或JQuery获得默认字体大小(以像素为单位)?
此问题询问有关获取默认字体大小的信息-这是将相对getDefaultFontSize()值转换为精确的offsetWidth值所必需的。
这个答案很好地解释了如何获取元素的默认字体大小:
由于ems可以测量宽度,因此您始终可以计算出确切的像素字体 通过创建一个长度为1000 ems的div并将其除以 client-Width属性减1000。我似乎记得ems被截断为 最接近的千分之一,因此您需要1000个em来避免错误 截断像素结果。
因此,以此答案为指导,我编写了以下函数来获取默认字体大小:
function getDefaultFontSize(parentElement)
{
parentElement = parentElement || document.body;
var div = document.createElement('div');
div.style.width = "1000em";
parentElement.appendChild(div);
var pixels = div.offsetWidth / 1000;
parentElement.removeChild(div);
return pixels;
}
有了默认字体大小后,只需将ems乘以元素的默认字体大小并将结果四舍五入,就可以将任何getDefaultFontSize()宽度转换为offsetWidth宽度。
getDefaultFontSize()
问题:理想情况下,getDefaultFontSize()应该是一个简单的,无副作用的函数,该函数返回默认字体大小。 但是它确实有一个不幸的副作用:它修改了DOM! 它附加一个孩子,然后删除该孩子。 为了获得有效的offsetWidth属性,必须追加孩子。 如果不将子项div附加到DOM,则offsetWidth属性将保持为0,因为从不渲染该元素。 即使我们立即删除了子元素,此功能仍然会产生意外的副作用,例如引发正在侦听父元素的事件(例如Internet Explorer的onpropertychange或W3C的DOMSubtreeModified事件)。
问题:是否有任何方法可以编写真正的免费副作用getDefaultFontSize()函数,而不会意外触发事件处理程序或引起其他意外副作用?
4个解决方案
26 votes
编辑:不,没有。
在不影响DOM的情况下获取给定元素的渲染字体大小:
parseFloat(getComputedStyle(parentElement).fontSize);
这是基于此问题的答案。
编辑:
在IE中,您必须使用2em,但这不能保证将大小转换为px。
此外,此代码段不会为您提供元素的默认字体大小,而是您的实际字体大小,如果它确实有一个与之关联的类和样式,则这很重要。 换句话说,如果元素的字体大小为2em,您将获得2个ems中的像素数。 除非内联指定字体大小,否则您将无法正确获得转换率。
mgiuffrida answered 2020-01-19T20:52:40Z
7 votes
我有一个更好的答案。 我的代码将在变量'getValue'中将1em值存储在unit-px中。
将此'getValue'放在HTML代码中的任何位置
'getValue'
将此函数放在您的JavaScript文件中
'getValue'
现在,每当您在参数中使用该测试div的ID调用此函数'getValue'时,您将拥有一个变量名称em,该变量将包含px的1 em值。
10011101111 answered 2020-01-19T20:53:22Z
3 votes
如果您需要快速而又肮脏的东西(并且基于主体的基本字体大小,而不是元素),我可以选择:
Number(getComputedStyle(document.body,null).fontSize.replace(/[^\d]/g, ''))
Number( // Casts numeric strings to number
getComputedStyle( // takes element and returns CSSStyleDeclaration object
document.body,null) // use document.body to get first "styled" element
.fontSize // get fontSize property
.replace(/[^\d]/g, '') // simple regex that will strip out non-numbers
) // returns number
Anthony answered 2020-01-19T20:53:42Z
1 votes
以下解决方案使用二进制搜索和window.matchMedia来查找窗口的em宽度。 然后,我们将窗口em宽度除以窗口像素宽度,以获得最终结果。不涉及DOM,无副作用!在性能方面,我的comp大约需要0.2ms的8次迭代。
const singleEmInPixels = getSingleEmInPixels();
console.log(`1em = ${singleEmInPixels}px`);
/**
* returns the amount of pixels for a single em
*/
function getSingleEmInPixels() {
let low = 0;
let high = 200;
let emWidth = Math.round((high - low) / 2) + low;
const time = performance.now();
let iters = 0;
const maxIters = 10;
while (high - low > 1) {
const match = window.matchMedia(`(min-width: ${emWidth}em)`).matches;
iters += 1;
if (match) {
low = emWidth;
} else {
high = emWidth;
}
emWidth = Math.round((high - low) / 2) + low;
if (iters > maxIters) {
console.warn(`max iterations reached ${iters}`);
break;
}
}
const singleEmPx = Math.ceil(window.innerWidth / emWidth);
console.log(`window em width = ${emWidth}, time elapsed = ${(performance.now() - time)}ms`);
return singleEmPx;
}
Nadav Parag answered 2020-01-19T20:54:03Z