В JavaScript/jQuery, как я могу масштабировать строку текста с изменяемой длиной текста в Div с фиксированной шириной, чтобы одна строка всегда входила внутрь Div (как одна строка)?
Спасибо.
В JavaScript/jQuery, как я могу масштабировать строку текста с изменяемой длиной текста в Div с фиксированной шириной, чтобы одна строка всегда входила внутрь Div (как одна строка)?
Спасибо.
Это что-то вроде взлома, но сделает то, что вы хотите.
<div id="hidden-resizer" style="visibility: hidden"></div>
Поместите это в нижней части страницы, где он не будет перемещать другие элементы на странице.
Затем сделайте следующее:
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());
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() );
});
Live demo: http://jsfiddle.net/e8B9j/2/show/
Удалите "/show/" из URL-адреса, чтобы просмотреть код.
Я написал плагин jQuery для этого:
http://michikono.github.com/boxfit
Плагин будет масштабировать текст как по горизонтали, так и по вертикали до максимально возможного размера внутри коробки, а затем центрировать его.
Единственное, что вам нужно сделать, это определить div с текстом внутри него:
<div id="scale">some text</div>
И затем вызовите:
$('#scale').boxfit()
Метод примет некоторые аргументы, чтобы отключить/включить перенос текста и центрированное выравнивание.
Для новых браузеров вы можете использовать Inline-SVG. Это можно масштабировать как изображение с помощью CSS..!
.smallerVersion{
max-width: 50%
}
<html>
<body>
<h2>Default version:</h2>
<svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
<style>
.small { font: italic 13px sans-serif; }
.heavy { font: bold 30px sans-serif; }
/* Note that the color of the text is set with the *
* fill property, the color property is for HTML only */
.Rrrrr { font: italic 40px serif; fill: red; }
</style>
<text x="20" y="35" class="small">My</text>
<text x="40" y="35" class="heavy">cat</text>
<text x="55" y="55" class="small">is</text>
<text x="65" y="55" class="Rrrrr">Grumpy!</text>
</svg>
<h2>Scaled version:</h2>
<svg class="smallerVersion" viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
<style>
.small { font: italic 13px sans-serif; }
.heavy { font: bold 30px sans-serif; }
/* Note that the color of the text is set with the *
* fill property, the color property is for HTML only */
.Rrrrr { font: italic 40px serif; fill: red; }
</style>
<text x="20" y="35" class="small">My</text>
<text x="40" y="35" class="heavy">cat</text>
<text x="55" y="55" class="small">is</text>
<text x="65" y="55" class="Rrrrr">Grumpy!</text>
</svg>
</body>
</html
Большинство других ответов используют цикл, чтобы уменьшить размер шрифта до тех пор, пока он не подходит для div, это ОЧЕНЬ медленно, так как страница должна повторно отображать элемент каждый раз, когда размер шрифта изменяется. В конечном итоге мне пришлось написать свой собственный алгоритм, чтобы он выполнялся таким образом, чтобы я мог периодически обновлять его содержимое, не замораживая пользовательский браузер. Я добавил некоторые другие функции (вращающийся текст, добавление дополнений) и упаковал его как плагин jQuery, вы можете получить его по адресу:
https://github.com/DanielHoffmann/jquery-bigtext
просто вызовите
$("#text").bigText();
и он будет хорошо вписываться в ваш контейнер.
Смотрите здесь:
http://danielhoffmann.github.io/jquery-bigtext/
Теперь, когда он имеет некоторые ограничения, div должен иметь фиксированную высоту и ширину и не поддерживает перенос текста на несколько строк.
Edit2: Я исправил эти проблемы и ограничения и добавил дополнительные параметры. Вы можете установить максимальный размер шрифта, и вы также можете ограничить размер шрифта с помощью ширины, высоты или обоих (по умолчанию оба). Я буду работать с принятием значений max-width и max-height в оберточном элементе.
Я не знаю точно, но здесь приближение:
var factor = 1/3; // approximate width-to-height ratio
var div = $('#mydiv');
div.css('font-size', div.width() / (div.text().length * factor) + 'px');
Вам нужно будет настроить factor
на основе используемого вами шрифта. 1/3, похоже, работает нормально для Times New Roman.
Внутри вашего div, введите текст в промежутке, который не имеет отступов. Тогда ширина пролета будет длиной текста.
Неиспользованный код для поиска правильного размера шрифта для использования:
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);
Проверьте этот пример!
Он использует jquery и отлично работает.
Изменить: Еще лучше http://plugins.jquery.com/project/TextFill
Вот решение coffeescript, с которым я столкнулся. Я клонирую элемент, который нужно изменить размер шрифта, а затем удалите его в конце вычисления. Для повышения производительности у меня есть код, который выполняет только вычисления после того, как изменение размера остановилось на 200 мс.
Элементы тега с классом autofont, чтобы это было сделано ненавязчиво.
#
# 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
Модифицированная версия @sworoc с поддержкой целевого класса
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();
}
resizeText("@arunoda", 350, $('#username'));
Я не мог понять, как добавить это в сообщение sworoc, но я думал, что все равно буду делиться: Решение Lonesomeday перепутано, если вы используете какую-либо навигацию AJAX. Я немного изменил его:
if ($('#hidden-resizer').length == 0){
$('<div />', {id: 'hidden-resizer'}).hide().appendTo(document.body);
}
У меня была аналогичная проблема, которая заставила меня написать мой собственный плагин для этого. Одним из решений является использование подхода с усадкой к подгонке, как описано выше. Однако, если вам нужно подогнать несколько элементов или иметь дело с производительностью, например, при изменении размера окна, посмотрите jquery-quickfit.
Он измеряет и вычисляет зависящий от размера размер сообщения для каждой буквы текста, который подходит, и использует его для вычисления следующего лучшего размера шрифта, который соответствует тексту в контейнере.
Вычисления кэшируются, что делает его очень быстрым (практически нет производительности при втором изменении размера вперёд) при работе с несколькими текстами или при необходимости иметь текст несколько раз, например, при изменении размера окна.
Здесь моя модификация предложения @teambob (в над комментариями), которая учитывает также высоту контейнера:
<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>
И затем..
$('.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());
});
См. Fiddle
Я сделал (еще) еще один плагин для решения этой проблемы:
https://github.com/jeremiahrose/perfectFit.js
Он генерирует SVG, поэтому он очень быстрый - просто запускается один раз при загрузке страницы. Способен автоматически переносить и масштабировать отдельные слова, чтобы точно соответствовать div.
вы можете делать несколько вещей, например
overflow:hidden
это сокращает дополнительную строку
overflow:auto
//это показывает полосу прокрутки
см. это
http://www.w3schools.com/Css/pr_pos_overflow.asp
попытайтесь сделать это // проверяем длину текста
if($('#idfortext').length>sometthing)
{
var fontsize=10;
}
$('#yourid').css('font-size',fontsize)
Я не уверен, что есть какой-либо точный способ измерения ширины текста в пикселях (именно это вы действительно ищете в корне вашей проблемы), так как каждый браузер может отображать шрифты по-разному. Возможно, вы захотите попробовать использовать этот CSS-код, в дополнение к изменению размера "Нечеткого" в зависимости от количества букв в предложении. Вы можете попробовать использовать шрифт фиксированной ширины (или стиль) для отображения текста, чтобы каждый символ занимал одинаковое пространство. Таким образом, вы можете сделать наилучшее предположение, и CSS по крайней мере даст вам хороший "...", прежде чем обрезать текст, если это необходимо.
.truncate
{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Я отработал несколько сообщений здесь и сделал из него плагин jQuery. Я обнаружил, что начиная со дна и поднимаясь, он был не очень впечатляющим, поэтому я делаю предположение, что текущий размер шрифта близок, и работал оттуда.
$.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);
Единственное, что получилось, это то, что он предполагает, что CSS для элемента является глобальным и применяется только к типу элемента. Другими словами, он создает тег с тем же именем и предполагает, что он будет иметь те же атрибуты CSS, что и элемент, который мы хотим изменить. Если это неверно для вас, просто измените строку, в которой создается resizer
.
чтобы соответствовать ширине и высоте контейнера
Вот мое решение: я измеряю текст в новом div в предоставленном div, так что стиль должен быть унаследован. Затем я вставляю текст в div с интервалом, чтобы установить размер шрифта. Он будет максимальным до размера шрифта по умолчанию, но будет уменьшаться.
Он не зацикливается: он только рисует текст один раз в метательном метатете перед рисованием непосредственно в предоставленный div. См. Ответ @Hoffmann - мне просто не понравился целый "плагин", чтобы ответить на вопрос.
требуется 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>');
}
Например:
<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>
Для тестирования: так я обнаружил, что мне нужен 1.1 pad_factor; которые вы можете настроить на свои нужды.
<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>
Примечание: предполагается, что размер шрифта px. Я не тестировал с em или pt.
Есть отличный способ сделать это для однострочных текстов, таких как заголовки и т.д., в чистом CSS:
h1{
font-size: 4.5vw;
margin: 0 0 0 0;
line-height: 1em;
height: 1em;
}
h1:after{
content:"";
display: inline-block;
width: 100%;
}
Убедитесь, что размер шрифта достаточно мал, чтобы сохранить строку заголовка 1. Использование "vw" (ширина видового экрана) вместо "px" делает очень простым сделать это и масштабировать в одно и то же время. ширина видового экрана имеет тенденцию ухудшаться, когда вы делаете свое окно браузера очень большим, многие сайты используют это, чтобы поддерживать сайт под определенной шириной на действительно широких экранах:
body{
max-width: 820px;
margin: 0 auto;
}
Чтобы убедиться, что ваш шрифт не зависит от того, насколько велико окно окна просмотра, когда остальная часть вашего сайта перестает масштабирование, используйте это:
@media(min-width:820px){
h1{
font-size: 30px;
}
}
Это то, что я нашел сегодня:
измерять ширину (w) height (h) текстового контейнера и делить на размер шрифта (f):
iw = w/f
ih = h/f
Разделите ширину основного контейнера (W) на iw и высоту основного контейнера (H) на ih:
kw = W/iw
kh = H/ih
Выберите наименьшее значение между kw и kh: это искомый FontSize.
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");
}
Это невозможно сделать. Я немного подумал об этом и исследовал его. Проблема в том, что существует так много переменных. Посмотрите на тот же сайт на сафари /firefox/IE. Посмотрите, как размер шрифта выглядит несколько иначе? Теперь взгляните на него на Linux/mac/iphone........
Если вы найдете решение, отправьте его здесь!
Решение найдено, я вижу... это замечательно!!