web-dev-qa-db-ja.com

jQuery / JavaScript:簡単な方法でピクセルをemに変換します

私のプロジェクトのレイアウトはemsである必要があるため、いくつかのピクセル値をem値に変換するために、コード行を私のプラグインに追加する簡単な方法を探しています。サードパーティのプラグインをサイトに追加したくないので、これを行う簡単な方法はありますか?.

プラグイン自体とは関係がないため、ここにコードを投稿しないでください。

ありがとう。

例:13px-> ?? em

22
user759235

あなたの質問は非常に重要だと思います。ディスプレイ解像度のクラスは急速に増加しているため、emポジショニングを使用して幅広い画面解像度をサポートすることは、非常に魅力的なアプローチです。しかし、すべてをemで保持しようとするのがどれほど困難であっても、JQueryのドラッグアンドドロップまたは別のライブラリからピクセル値を取得する場合があり、永続化のためにサーバーに送信する前にこの値をemに変換する必要があります。そうすれば、次にユーザーがページを見るときに、使用しているデバイスの画面解像度に関係なく、アイテムは正しい位置に表示されます。

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';
};
_

使用例:$(myPixelValue).toEm();または$(myEmValue).toPx();

私は自分のアプリケーションでこれをテストしましたが、うまくいきます。だから私は共有すると思いました。

18
Aras

以下は、親の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概念実証

ノート:

  • emに変換しようとしている要素がbodyである場合、関数はfalseを返しますが、これは、値を1emまたはそのままにしておきます。

  • window.getComputedStyle()を使用しているため、調整を行わないとIEで動作しません。

参照:

ピクセルとemsは、基本的に異なるタイプのユニットです。それらの間で単純に変換することはできません。

たとえば、トップレベルの見出しが200%のフォントサイズでスタイル設定されているサイトで、デフォルトのフォントサイズが16pxのユーザーの場合、1emは32pxに等しい場合があります。見出しをドキュメント内の別の場所に移動します。64pxまたは16pxにすることができます。同じドキュメントを別のユーザーに渡すと、30/60/15pxになる場合があります。別の要素について話し始めると、再び変わる可能性があります。

ピクセルからems + document + context + settingsに変換するのが最も近い方法です。しかし、誰かがemsを使用してプロジェクトをレイアウトするように依頼した場合、ピクセルで実行してから「変換」しようとしていることにおそらく不満を抱くでしょう。

3
Jim

古い質問ですが、参考までに、私がまとめたものを示します。スコープとサフィックスはオプションです。たとえば、文字列としてremまたはem値を渡します。 '4em' [スペースと大文字/小文字を使用できます]とすると、px値が返されます。ローカルEM値を見つけるためのターゲット要素となるスコープを指定しない限り、デフォルトで本文になり、実質的にrem値が提供されます。最後に、オプションのサフィックスパラメータ[boolean]は、たとえば48が48pxになるように、戻り値に「px」を追加します。

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

font-size 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;
  };
1

通常、pxemに変換する場合、要素自体で変換が行われます。 getComputedStylepxに値を返し、応答性が損なわれます。以下のコードを使用して、この問題を解決できます。

/**
 * 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;
};

使い方は次のように簡単です:

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

この機能をライブラリーにパッケージ化し、パラメータータイプチェックを完了しました: px-to-em

このHTMLを考えると:

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

これらの出力を期待できます:

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

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>

私は この答え から学びました。getComputedStyleを使用すると、小数点付きの除数px値を確実に取得できるため、計算の精度が向上します。 Arasの回答が0.5px以上ずれている可能性があることがわかりました。これにより、丸めエラーが発生しました。

0
Jackson

これを使ってみてください:

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