jQuery/JavaScript:以简单的方式将像素转换为 em

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10305993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:46:58  来源:igfitidea点击:

jQuery/JavaScript: convert pixels to em in a easy way

javascriptjquerypixelem

提问by user759235

I am looking for a easy way to add a line of code to a plugin of mine, to convert a couple of pixel values into em values, because the layout of my project needs to be in ems. Is there an easy way to do this, because I don't want to add a third-party plugin to the site.

我正在寻找一种简单的方法来向我的插件添加一行代码,将几个像素值转换为 em 值,因为我的项目的布局需要在 ems 中。有没有一种简单的方法可以做到这一点,因为我不想向网站添加第三方插件。

Won't post the code here, as it has nothing to do with the plugin it self.

不会在这里发布代码,因为它与插件本身无关。

Thanks.

谢谢。

Example: 13px -> ??em

示例:13px -> ??em

回答by Aras

I think your question is very important. Since the classes of display resolutions are rapidly increasing, using em positioning to support wide range of screen resolutions is a really appealing approach. But no matter how hard you try to keep everything in em -- sometimes you get a pixel value maybe from JQuery drag and drop or from another library, and you would want to convert this value to em before sending it back to server for persistence. That way next time user looks at the page, item would be in correct position -- regardless of screen resolution of the device they are using.

我认为你的问题非常重要。由于显示分辨率的类别正在迅速增加,使用 em 定位来支持广泛的屏幕分辨率是一种非常有吸引力的方法。但是无论您多么努力地将所有内容都保留在 em 中——有时您可能会从 JQuery 拖放或其他库中获得一个像素值,并且您希望在将其发送回服务器以进行持久化之前将该值转换为 em。这样下次用户查看页面时,项目将处于正确位置 - 无论他们使用的设备的屏幕分辨率如何。

JQuery plugins are not very scary when you can review the code, specially if they are short and sweet like this plugin to convert pixel values to emas you want. In fact it is so short I will paste the whole thing here. For copyright notice see the link.

当您可以查看代码时,JQuery 插件并不是很可怕,特别是如果它们像这个插件一样简短而甜美,可以根据需要将像素值转换为 em。事实上,它太短了,我将把整个内容贴在这里。版权声明见链接。

$.fn.toEm = function(settings){
    settings = jQuery.extend({
        scope: 'body'
    }, settings);
    var that = parseInt(this[0],10),
        scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;">&nbsp;</div>').appendTo(settings.scope),
        scopeVal = scopeTest.height();
    scopeTest.remove();
    return (that / scopeVal).toFixed(8) + 'em';
};


$.fn.toPx = function(settings){
    settings = jQuery.extend({
        scope: 'body'
    }, settings);
    var that = parseFloat(this[0]),
        scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;">&nbsp;</div>').appendTo(settings.scope),
        scopeVal = scopeTest.height();
    scopeTest.remove();
    return Math.round(that * scopeVal) + 'px';
};

Usage Example: $(myPixelValue).toEm();or $(myEmValue).toPx();.

用法示例:$(myPixelValue).toEm();$(myEmValue).toPx();

I just tested this in my application, it works great. So I thought I share.

我刚刚在我的应用程序中对此进行了测试,效果很好。所以我想我分享。

回答by David says reinstate Monica

The following seems to do as you require, though it's based on the font-sizeof the parent, and of the element itself, being returned in px:

以下内容似乎按照您的要求执行,尽管它基于font-size父元素的 和元素本身,在 中返回px

function px2em(elem) {
    var W = window,
        D = document;
    if (!elem || elem.parentNode.tagName.toLowerCase() == 'body') {
        return false;
    }
    else {
        var parentFontSize = parseInt(W.getComputedStyle(elem.parentNode, null).fontSize, 10),
            elemFontSize = parseInt(W.getComputedStyle(elem, null).fontSize, 10);

        var pxInEms = Math.floor((elemFontSize / parentFontSize) * 100) / 100;
        elem.style.fontSize = pxInEms + 'em';
    }
}

JS Fiddle proof of concept.

JS Fiddle 概念验证

Notes:

笔记:

  • The function returns false, if the element you're trying to convert to emis the body, though that's because I couldn't work out whether it was sensible to set the value to 1emor simply leave it alone.

  • It uses window.getComputedStyle(), so it's not going to work with IE, without some adjustments.

  • 函数返回false,如果你想转换的元素embody,虽然那是因为我不能工作了,是否是明智的值设置为1em或者干脆息事宁人。

  • 它使用window.getComputedStyle(),因此如果不进行一些调整,它将无法与 IE 一起使用。

References:

参考:

回答by Jim

Pixels and ems are fundamentally different types of unit. You can't simply convert between them.

像素和 em 是根本不同类型的单位。您不能简单地在它们之间进行转换。

For instance, a user with a default font size of 16px on a site where top-level headings are styled at 200% font size, 1em may be equal to 32px. Move the heading elsewhere in the document, it could be 64px or 16px. Give the same document to a different user, it might be 30/60/15px. Start talking about a different element, and it can change again.

例如,在顶级标题以 200% 字体大小设置样式的站点上,默认字体大小为 16px 的用户,1em 可能等于 32px。将标题移动到文档中的其他位置,可以是 64 像素或 16 像素。将相同的文档交给不同的用户,可能是 30/60/15px。开始谈论一个不同的元素,它可以再次改变。

The closest you can come to what you want is to convert from pixels to ems+document+context+settings. But if somebody has asked you to lay out your project with ems, they will probably not be pleased that you are trying to do it in pixels then "converting".

最接近你想要的是从像素转换为 ems+document+context+settings。但是如果有人要求你用 em 来布置你的项目,他们可能不会因为你试图以像素为单位然后“转换”而感到高兴。

回答by whatsnewsisyphus

Old question, but for reference, here is something I cobbled together, scope and suffix are optional. Pass it a rem or em value as string, eg. '4em' [ you can use spaces and upper/lowercase ] and it will return the px value. Unless you give it a scope, which would be the target element for finding the local EM value, it will default to body, effectively giving you the rem value. Lastly, the optional suffix parameter [ boolean ] will add 'px' to the returned value such that 48 becomes 48px for example.

老问题,但作为参考,这是我拼凑的东西,范围和后缀是可选的。将 rem 或 em 值作为字符串传递给它,例如。'4em' [你可以使用空格和大写/小写],它将返回像素值。除非你给它一个范围,这将是查找本地 EM 值的目标元素,否则它将默认为 body,有效地为你提供 rem 值。最后,可选的后缀参数 [boolean] 将向返回值添加“px”,例如 48 变为 48px。

ex: emRemToPx( '3em', '#content' )

前任: emRemToPx( '3em', '#content' )

return 48 on a font-size 16px / 100% document

在字体大小为 16px / 100% 的文档上返回 48

/**
* emRemToPx.js | @whatsnewsisyphus 
* To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
* see CC0 Public Domain Dedication <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
  var emRemToPx = function( value, scope, suffix ) {
    if (!scope || value.toLowerCase().indexOf("rem") >= 0) {
      scope = 'body';
    }
    if (suffix === true) {
      suffix = 'px';
    } else {
      suffix = null;
    }
    var multiplier = parseFloat(value);
    var scopeTest = $('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;">&nbsp;</div>').appendTo(scope);
    var scopeVal = scopeTest.height();
    scopeTest.remove();
    return Math.round(multiplier * scopeVal) + suffix;
  };

回答by Nicolas Bouvrette

Usually when you want to convert pxto em, the conversion happens on the element itself. getComputedStylereturns value in pxwhich break their responsiveness. The code below can be used to help with this issue:

通常,当您想转换px为 时em,转换发生在元素本身上。getComputedStyle返回值,px其中破坏了他们的响应能力。下面的代码可用于帮助解决此问题:

/**
 * Get the equivalent EM value on a given element with a given pixel value.
 *
 * Normally the number of pixel specified should come from the element itself (e.g. element.style.height) since EM is
 * relative.
 *
 * @param {Object} element - The HTML element.
 * @param {Number} pixelValue - The number of pixel to convert in EM on this specific element.
 *
 * @returns {Boolean|Number} The EM value, or false if unable to convert.
 */
window.getEmValueFromElement = function (element, pixelValue) {
    if (element.parentNode) {
        var parentFontSize = parseFloat(window.getComputedStyle(element.parentNode).fontSize);
        var elementFontSize = parseFloat(window.getComputedStyle(element).fontSize);
        var pixelValueOfOneEm = (elementFontSize / parentFontSize) * elementFontSize;
        return (pixelValue / pixelValueOfOneEm);
    }
    return false;
};

Using it would be as simple as:

使用它就像这样简单:

var element = document.getElementById('someDiv');
var computedHeightInEm = window.getEmValueFromElement(element, element.offsetHeight);

回答by Hymanson

I've packaged this functionality into a library, complete with parameter type checking: px-to-em

我已将此功能打包到一个库中,并完成了参数类型检查: px-to-em

Given this HTML:

鉴于此 HTML:

<p id="message" style="font-size: 16px;">Hello World!</p>

You can expect these outputs:

您可以期待这些输出:

pxToEm(16, message) === 1
pxToEm(24, message) === 1.5
pxToEm(32, message) === 2

Since the OP requested a way to do this without a library, I've copied the source code of px-to-emto a live demo:

由于 OP 要求一种无需库即可执行此操作的方法,因此我已将 的源代码复制px-to-em到现场演示中:

function pxToEm (px, element) {
  element = element === null || element === undefined ? document.documentElement : element;
  var temporaryElement = document.createElement('div');
  temporaryElement.style.setProperty('position', 'absolute', 'important');
  temporaryElement.style.setProperty('visibility', 'hidden', 'important');
  temporaryElement.style.setProperty('font-size', '1em', 'important');
  element.appendChild(temporaryElement);
  var baseFontSize = parseFloat(getComputedStyle(temporaryElement).fontSize);
  temporaryElement.parentNode.removeChild(temporaryElement);
  return px / baseFontSize;
}

console.log(pxToEm(16, message), 'Should be 1');
console.log(pxToEm(24, message), 'Should be 1.5');
console.log(pxToEm(32, message), 'Should be 2');
<p id="message" style="font-size: 16px;">Hello World!</p>

I learned from this answerthat with getComputedStylewe can reliably obtain the divisor px value with the decimal point, which improves the accuracy of the calculation. I found that the answer by Aras could be off by over 0.5px, which caused rounding errors for us.

我从这个答案中了解到,有了getComputedStyle我们可以可靠地获得带小数点的除数px值,这提高了计算的准确性。我发现 Aras 的答案可能会偏离 0.5px 以上,这给我们带来了舍入错误。

回答by Tehila

Try using this:

尝试使用这个:

parseInt(myPixelValue) / parseFloat($("body").css("font-size"));

回答by Brad

Ems don't equal pixels in anyway. They are a relative measurement.

无论如何,Ems 并不等于像素。它们是相对测量。

<span style="font-size: 1em;">This is 1em font size, which means the text is the same size as the parent</span>

<span style="font-size: 1.5em;">This is 1.5em font size, which means the text is 150% the size as the parent</span>

The base size is determined by the user-agent (browser).

基本大小由用户代理(浏览器)决定。