javascript - bootstrap - tooltip jquery
Texto de escala de JavaScript para ajustar en Div fijo (22)
En JavaScript / jQuery, ¿cómo puedo escalar una línea de texto de longitud variable dentro de una Div de ancho fijo para que la línea siempre se ajuste dentro de la Div (como una línea)?
Gracias.
Aquí está mi modificación a la sugerencia de @ teambob (en los comentarios anteriores ) que también tiene en cuenta la altura del contenedor:
<div class="box" style="width:700px; height:200px">This is a sentence</div>
<div class="box" style="width:600px; height:100px">This is a sentence</div>
<div class="box" style="width:500px; height:50px">This is a sentence</div>
<div class="box" style="width:400px; height:20px">This is a sentence</div>
Y entonces..
$(''.box'').each(function(i, box) {
var width = $(box).width(),
height = $(box).height(),
html = ''<span style="white-space:nowrap">'',
line = $(box).wrapInner(html).children()[0],
maxSizePX = 2000;
$(box).css(''font-size'', maxSizePX);
var widthFontSize = Math.floor(width/$(line).width()*maxSizePX),
heightFontSize = Math.floor(height/$(line).height()*maxSizePX),
maximalFontSize = Math.min(widthFontSize, heightFontSize, maxSizePX);
$(box).css(''font-size'', maximalFontSize);
$(box).text($(line).text());
});
Ver Fiddle
Aquí está mi solución: mido el texto en un nuevo div dentro del div proporcionado, para que el estilo se herede. Luego inserto el texto en el div con un lapso para establecer el tamaño de la fuente. Se maximizará hasta el tamaño de fuente predeterminado, pero se reducirá para ajustarse.
No se repite: solo dibuja el texto una vez en un div desprendible antes de dibujarse directamente en el div suministrado. Ver la respuesta de @Hoffmann: simplemente no me gustó todo un ''complemento'' para responder la pregunta.
requiere jquery.
var txt = txt || {}
txt.pad_factor = 1.1;
txt.insertText_shrinkToFit = function(div,text)
{
var d = txt.cache || $(''<div></div>'');
txt.cache = d;
d.css(''white-space'',''nowrap'');
d.css(''position'',''absolute'');
d.css(''top'',''-10000px'');
d.css(''font-size'',''1000px'');
var p = $(div);
var max_w = parseInt(p.css(''max-width'')) || p.width();
var max_h = parseInt(p.css(''font-size''));
p.append(d);
d.html(text);
var w = d.width() * txt.pad_factor;
d.remove();
var h = Math.floor(max_w*1000/w);
var s = ( max_h < h ? max_h : h ) + "px";
p.html(''<SPAN style="font-size:'' + s + ''">'' + text + ''</SPAN>'');
}
Por ejemplo:
<html><head><script src=http://code.jquery.com/jquery-latest.min.js></script>
<script>/*insert code, from above, here.*/</script></head><body>
<div id=mysmalldiv style="max-width:300px;font-size:50px"></div>
<script>
txt.insertText_shrinkToFit("#mysmalldiv","My super long text for this div.");
</script>
</body></html>
Para probar: así es como descubrí que necesitaba el 1.1 pad_factor; que puedes sintonizar con tus necesidades
<div id=mytestdiv style="max-width:300px;font-size:50px"></div>
<script>
var t = "my text ";
var i = 0;
var f = function() {
t += i + " ";
txt.insertText_shrinkToFit("#mytestdiv",t);
i++;
if(i < 100)
setTimeout(f,1000);
}
f();
</script>
Nota: esto está asumiendo px font-size. No he probado con em o pt.
Aquí hay una solución coffeescript que se me ocurrió. Cloné el elemento que necesita cambiar el tamaño de su fuente y luego lo eliminé al final del cálculo. Para aumentar el rendimiento, tengo un código que solo ejecuta el cálculo después de que el cambio de tamaño se detuvo durante 200 ms.
Etiquetar los elementos con autofont de clase para que esto se haga discretamente.
#
# Automagically resize fonts to fit the width of the
# container they are in as much as possible.
#
fixfonts = ->
scaler = 1.2
for element in $(''.autofont'')
size = 1
element = $(element)
desired_width = $(element).width()
resizer = $(element.clone())
resizer.css
''font-size'': "#{size}em"
''max-width'': desired_width
''display'': ''inline''
''width'': ''auto''
resizer.insertAfter(element)
while resizer.width() < desired_width
size = size * scaler
resizer.css
''font-size'': "#{size}em"
$(element).css
''font-size'': "#{size / scaler }em"
resizer.remove()
$(document).ready =>
fixfonts()
timeout = 0
doresize = ->
timeout--
if timeout == 0
fixfonts()
$(window).resize ->
timeout++
window.setTimeout doresize, 200
Dentro de su div, tenga el texto en un lapso que no tenga relleno. Entonces el ancho del tramo será la longitud del texto.
Código no probado para encontrar el tamaño de letra correcto para usar:
var objSpan = $(''.spanThatHoldsText'');
var intDivWidth = $(''.divThatHasAFixedWidth'').width();
var intResultSize;
for (var intFontSize = 1; intFontSize < 100; intFontSize++)
objSpan.css(''font-size'', intFontSize);
if (objSpan.width() > intDivWidth) {
intResultSize = intFontSize - 1;
break;
}
}
objSpan.css(''font-size'', intResultSize);
Esto es algo así como un hack, pero hará lo que quieras.
<div id="hidden-resizer" style="visibility: hidden"></div>
Coloque esto en la parte inferior de su página, donde no moverá otros elementos en la página.
Entonces haz esto:
var size;
var desired_width = 50;
var resizer = $("#hidden-resizer");
resizer.html("This is the text I want to resize.");
while(resizer.width() > desired_width) {
size = parseInt(resizer.css("font-size"), 10);
resizer.css("font-size", size - 1);
}
$("#target-location").css("font-size", size).html(resizer.html());
Esto es lo que encontré hoy:
- Establecer un tamaño de fuente falso grande (f) para el texto de destino
mida el ancho (w) de altura (h) del contenedor de texto y divida por tamaño de fuente (f):
-
iw = w/f
-
ih = h/f
-
Divida el ancho del contenedor principal (W) por iw y la altura del contenedor principal (H) por ih:
-
kw = W/iw
-
kh = H/ih
-
Elija el valor más bajo entre kw y kh: ese es FontSize deseado.
https://jsfiddle.net/pinkynrg/44ua56dv/
function maximizeFontSize($target) {
var testingFont = 1000;
$target.find(".text-wrapper").css("font-size", testingFont+"px");
var textWidth = $(".text-wrapper").width()/1000;
var textHeight = $(".text-wrapper").height()/1000;
var width = $(".container").width();
var height = $(".container").height();
var kWidth = width/textWidth;
var kHeight = height/textHeight;
var fontSize = kWidth < kHeight ? kWidth : kHeight;
// finally
$(".text-wrapper")
.css("font-size", fontSize+"px")
.css("line-height", height+"px");
}
HTML:
<div class="box" style="width:700px">This is a sentence</div>
<div class="box" style="width:600px">This is a sentence</div>
<div class="box" style="width:500px">This is a sentence</div>
<div class="box" style="width:400px">This is a sentence</div>
JavaScript:
$( ''.box'' ).each(function ( i, box ) {
var width = $( box ).width(),
html = ''<span style="white-space:nowrap"></span>'',
line = $( box ).wrapInner( html ).children()[ 0 ],
n = 100;
$( box ).css( ''font-size'', n );
while ( $( line ).width() > width ) {
$( box ).css( ''font-size'', --n );
}
$( box ).text( $( line ).text() );
});
Demostración en vivo: http://jsfiddle.net/e8B9j/2/show/
Elimina "/ show /" de la URL para ver el código.
Hay una gran manera de hacer esto para textos de una sola línea, como encabezados y demás, en CSS puro:
h1{
font-size: 4.5vw;
margin: 0 0 0 0;
line-height: 1em;
height: 1em;
}
h1:after{
content:"";
display: inline-block;
width: 100%;
}
Asegúrese de que el tamaño de letra sea lo suficientemente pequeño como para mantener la línea del encabezado 1. Usar ''vw'' (ancho de ventana gráfica) en lugar de ''px'' hace que sea muy fácil hacer esto y escalar al mismo tiempo. El ancho de la ventana gráfica tiende a ponerse desagradable cuando haces que la ventana de tu navegador sea muy grande. Muchos sitios usan esto para mantener el sitio bajo cierto ancho en pantallas realmente anchas:
body{
max-width: 820px;
margin: 0 auto;
}
Para asegurarse de que su fuente no se base en cuán grande sea la ventana de la ventana gráfica una vez que el resto de su sitio deje de escalar, use esto:
@media(min-width:820px){
h1{
font-size: 30px;
}
}
He escrito un complemento jQuery para hacer esto:
http://michikono.github.com/boxfit
El complemento escalará el texto tanto horizontal como verticalmente hasta el tamaño máximo disponible dentro del cuadro y luego lo centrará.
Lo único que debe hacer es definir un div con texto dentro de él:
<div id="scale">some text</div>
Y luego llama:
$(''#scale'').boxfit()
El método aceptará algunos argumentos para deshabilitar / habilitar el ajuste de texto y la alineación centrada.
Hice (todavía) otro complemento para abordar este problema:
https://github.com/jeremiahrose/perfectFit.js
Genera SVG por lo que es muy rápido, solo se ejecuta una vez en la carga de la página. Capaz de envolver y escalar automáticamente palabras individuales para ajustarse exactamente a un div.
La mayoría de las otras respuestas utilizan un bucle para reducir el tamaño de letra hasta que se ajusta al div, esto es MUY lento, ya que la página necesita volver a representar el elemento cada vez que la fuente cambia de tamaño. Eventualmente tuve que escribir mi propio algoritmo para hacerlo funcionar de una manera que me permitiera actualizar sus contenidos periódicamente sin congelar el navegador del usuario. Agregué algunas otras funcionalidades (rotación de texto, agregando relleno) y las empaqué como un complemento de jQuery, puedes obtenerlo en:
github.com/DanielHoffmann/jquery-bigtext
simplemente llame
$("#text").bigText();
y se ajustará muy bien en su contenedor.
Véalo en acción aquí:
http://danielhoffmann.github.io/jquery-bigtext/
Por ahora tiene algunas limitaciones, el div debe tener una altura y ancho fijos y no admite el ajuste de texto en varias líneas.
Edit2: ahora solucioné esos problemas y limitaciones y agregué más opciones. Puede establecer el tamaño máximo de fuente y también puede optar por limitar el tamaño de fuente usando ancho, alto o ambos (el valor predeterminado es ambos). Trabajaré para aceptar los valores de ancho máximo y alto máximo en el elemento contenedor.
No es posible hacer He pensado un poco sobre esto y lo investigué. El problema es que hay tantas variables. Mira el mismo sitio en safari / firefox / IE. ¿Ves cómo los tamaños de fuente se ven ligeramente diferentes? Ahora ve a verlo en Linux / Mac / iphone ........
¡Si encuentra una solución, publíquela aquí!
Solución encontrada, veo ... ¡¡eso es genial !!
No estoy seguro de que haya alguna manera precisa de medir el ancho del texto en píxeles (que es lo que realmente está buscando en la raíz de su problema), ya que cada navegador puede mostrar las fuentes de manera diferente. Es posible que desee intentar usar este código CSS, además de hacer un cambio de tamaño "Fuzzy" basado en el número de letras de la oración. Puede intentar usar una fuente (o estilo) de ancho fijo para mostrar el texto de modo que cada personaje ocupe la misma cantidad de espacio. De esta forma, puede hacer una mejor suposición, y el CSS al menos le dará un buen "..." antes de recortar el texto, si es necesario.
.truncate
{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
No pude encontrar la manera de agregar esto a la publicación de sworoc, pero pensé que podría compartirlo de todos modos: la solución de Lonesomeday se estropea si estás utilizando algún tipo de navegación AJAX. Lo modifiqué ligeramente para:
if ($(''#hidden-resizer'').length == 0){
$(''<div />'', {id: ''hidden-resizer''}).hide().appendTo(document.body);
}
No sé de una manera exacta, pero aquí hay una aproximación:
var factor = 1/3; // approximate width-to-height ratio
var div = $(''#mydiv'');
div.css(''font-size'', div.width() / (div.text().length * factor) + ''px'');
Tendrá que ajustar el factor
función de la fuente que está utilizando. 1/3 parece funcionar bien para Times New Roman.
Para los nuevos navegadores, puede usar Inline-SVG. Esto se puede escalar como una imagen a través de CSS ...! ( width: 100%;
)
Trabajé en algunas publicaciones aquí e hice un plugin de jQuery. Descubrí que comenzar desde abajo y subir no era muy efectivo, así que supongo que el tamaño de fuente actual está cerca, y funcionó a partir de ahí.
$.fn.fitTextToWidth = function(desiredWidth) {
// In this method, we want to start at the current width and grow from there, assuming that we are close to the desired size already.
var $el = $(this);
var resizer = $(''<''+$el.get(0).tagName+'' />'').css({''vsibility'':''hidden'',''position'':''absolute'',''left'':''-9999px'',''display'':''inline''}).html($el.html());
resizer.appendTo(document.body);
var size = parseInt($el.css(''font-size''));
resizer.css(''font-size'',size+''px'');
var growing = desiredWidth > resizer.width() ? true : false;
var adder = growing ? 1 : -1;
do {
size += adder;
resizer.css(''font-size'',size+''px'');
} while(((growing && resizer.width()<desiredWidth) || (!growing && resizer.width()>desiredWidth)) && size>10 && size<100);
if (growing)
size -= 2; //we never want to go over
resizer.remove();
$el.css(''font-size'',size+''px'');
}
// Example use:
$(''#main h1'').fitTextToWidth(350);
El único problema con esto es que supone que el CSS para el elemento es global y solo se aplica al tipo de elemento. En otras palabras, crea una etiqueta con el mismo nombre y asume que tendrá los mismos atributos de CSS que el elemento que queremos cambiar. Si esto no es cierto para usted, simplemente modifique la línea donde se crea el resizer
.
Tuve un problema similar, que me hizo escribir mi propio complemento para esto. Una solución es usar el enfoque de encogimiento para ajustar, como se describió anteriormente. Sin embargo, si tiene que caber en varios elementos o si le preocupa el rendimiento, por ejemplo, en el cambio de tamaño de la ventana, eche un vistazo a jquery-quickfit .
Mide y calcula una medida invariante de tamaño para cada letra del texto que se ajusta y usa esto para calcular el siguiente mejor tamaño de letra que encaje con el texto en el contenedor.
Los cálculos se almacenan en caché, lo que lo hace muy rápido (prácticamente no se produce ningún impacto desde el segundo cambio de tamaño al avanzar) cuando se trabaja con varios textos o se tiene que ajustar un texto varias veces, como por ejemplo, en el tamaño de la ventana.
Versión modificada de @sworoc con el soporte de la clase objetivo
function resizeText(text, size, target) {
var fontSize = 0;
var resizer = $(''<span>'');
resizer.html(text).hide();
resizer.attr(''class'', target.attr(''class''));
$(''body'').append(resizer);
while(resizer.width() < size) {
fontSize++
resizer.css("font-size", fontSize);
}
target.css(''font-size'', fontSize).html(text);
resizer.remove();
}
Uso
resizeText("@arunoda", 350, $(''#username''));
complemento para adaptarse al ancho y alto de un contenedor
puedes hacer muchas cosas como
overflow:hidden
esto corta la línea adicional
overflow:auto
// esto muestra la barra de desplazamiento
mira esto
http://www.w3schools.com/Css/pr_pos_overflow.asp
intente hacer esto // verifique la longitud del texto
if($(''#idfortext'').length>sometthing)
{
var fontsize=10;
}
$(''#yourid'').css(''font-size'',fontsize)
¡Mira este ejemplo! Utiliza jquery y funciona bien.
Editar: Aún mejor uno http://plugins.jquery.com/project/TextFill