2012-04-24 32 views
19

Estoy buscando una manera fácil de agregar una línea de código a un complemento mío, para convertir un par de valores de píxeles en valores em, porque el diseño de mi proyecto debe estar en ems. ¿Hay una manera fácil de hacer esto, porque no quiero agregar un complemento de terceros al sitio?jQuery/JavaScript: convertir píxeles a em de una manera fácil

No se publicará el código aquí, ya que no tiene nada que ver con el complemento.

Gracias.

Ejemplo: 13px -> ?? em

+3

esto podría ayudarlo http://pxtoem.com/ Compruebe la pestaña "aprender" – chepe263

Respuesta

3

píxeles y ems son fundamentalmente diferentes tipos de unidad. No puedes simplemente convertir entre ellos.

Por ejemplo, un usuario con un tamaño de fuente predeterminado de 16px en un sitio donde las partidas de nivel superior están decoradas en 200% tamaño de fuente, 1 em puede ser igual a 32px. Mueva el encabezado a otra parte del documento, podría ser 64px o 16px. Entregue el mismo documento a un usuario diferente, puede ser 30/60/15 px. Comience a hablar sobre un elemento diferente, y puede cambiar de nuevo.

Lo más cerca que puede llegar a lo que desea es convertir de píxeles a ems + documento + contexto + configuración. Pero si alguien te ha pedido que diseñe tu proyecto con ems, probablemente no estén contentos de que estés tratando de hacerlo en píxeles y luego "convirtiendo".

+5

hay casos válidos cuando solo tiene acceso al valor de píxel. Por ejemplo, al arrastrar un div alrededor de la página, es posible que desee obtener el valor em antes de persistir en la posición del div. Creo que la pregunta es perfectamente válida y es posible convertir píxeles a em si lo haces dentro del navegador. Después de todo, el navegador convierte los valores em en píxeles antes de renderizar. – Aras

0

Ems no son iguales a los píxeles de todos modos. Son una medida relativa.

<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> 

El tamaño de base viene determinado por el usuario-agente (navegador).

+0

El tamaño de la base está determinado por el tamaño de fuente o el tamaño de fuente de los padres. Si alguien tiene font-size definido, user-agent. – joseantgv

+0

@joseantgv Sí, de acuerdo. Intento decir que el tamaño en la base de todo está a nivel de agente de usuario. – Brad

15

El siguiente parece hacer como sea necesario, aunque se basa en la font-size de los padres y del propio elemento, siendo devueltos en 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.

Notas:

  • La función retorna falso, si el elemento que está tratando de convertir a em es la body, aunque eso es porque no podía trabajar si era razonable para establecer el valor a 1em o simplemente déjalo en paz.

  • Utiliza window.getComputedStyle(), por lo que no va a funcionar con IE, sin algunos ajustes.

Referencias:

+3

+1, para referencias MDN. – saji89

17

Creo que su pregunta es muy importante. Dado que las clases de resoluciones de pantalla están aumentando rápidamente, utilizar el posicionamiento em para admitir una amplia gama de resoluciones de pantalla es un enfoque realmente atractivo. Pero no importa cuánto intentes guardar todo en ellos, a veces obtienes un valor de píxel de JQuery arrastrando y soltando o de otra biblioteca, y querrás convertir este valor en em antes de enviarlo al servidor para su persistencia. De esta manera, la próxima vez que el usuario mire la página, el elemento estará en la posición correcta, independientemente de la resolución de pantalla del dispositivo que esté utilizando.

Los complementos de JQuery no son muy aterradores cuando puede revisar el código, especialmente si son cortos y agradables como this plugin to convert pixel values to em como desee. De hecho, es tan corto que pegaré todo aquí. Para ver el aviso de copyright, consulte el enlace.

$.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'; 
}; 

Ejemplo de uso: $(myPixelValue).toEm(); o $(myEmValue).toPx();.

Acabo de probar esto en mi aplicación, funciona muy bien. Así que pensé que compartir

+0

Nunca he visto jQuery usado así. Supongo que esto admite valores de cadena ('" 3px "' o '" 3em "'), pero eso no le pide a jQuery que consulte el documento para esos selectores, antes de llegar al plugin '.toPx()' o '.toEm()'? –

1

Pregunta anterior, pero como referencia, aquí hay algo que improvisé, el alcance y el sufijo son opcionales. Pasarle un valor rem o em como una cadena, ej. '4em' [puede usar espacios y mayúsculas/minúsculas] y devolverá el valor de px. A menos que le dé un alcance, que sería el elemento objetivo para encontrar el valor de EM local, se establecerá de forma predeterminada en el cuerpo, lo que le proporcionará efectivamente el valor de rem. Por último, el parámetro de sufijo opcional [booleano] agregará 'px' al valor devuelto de modo que 48 se convierta 48px por ejemplo.

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

de retorno 48 en un tamaño de fuente de 16 píxeles/100% documento

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

Comprobar este pequeño script de salida: https://github.com/normanzb/size

que le ayuda a convertir las unidades, siempre y a medida que pasa en un elemento dom de referencia

0

Por lo general, cuando desea convertir px a em, la conversión ocurre en el elemento mismo. getComputedStyle devuelve valor en px que interrumpe su receptividad.El código siguiente se puede utilizar para ayudar con este problema:

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

Su uso podría ser tan simple como:

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

He envasados ​​esta funcionalidad en una biblioteca, con la comprobación de tipos de parámetros: px-to-em

Teniendo en cuenta este código HTML:

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

Usted puede esperar que estos outp UTS:

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

Desde el PO pidió una manera de hacer esto sin una biblioteca, he copiado el código fuente de px-to-em a una demostración en vivo:

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 aprendí de this answer que con getComputedStyle podemos obtener de manera confiable el valor px de divisor con el punto decimal, lo que mejora la precisión del cálculo. Descubrí que la respuesta de Aras podría estar por encima de 0.5px, lo que nos causó errores de redondeo.

Cuestiones relacionadas