根据其父容器检查文本元素的宽度(基于字体大小)
Posted
技术标签:
【中文标题】根据其父容器检查文本元素的宽度(基于字体大小)【英文标题】:Checking a text element's width (based on font-size) against its parent container 【发布时间】:2013-03-03 14:41:43 【问题描述】:我带着一个棘手的问题来找你:
假设您有以下基本结构:
<div><p>hello</p></div>
现在假设 div 有display:block; and width:200px;
。
使用 javascript,你将如何检查什么字体大小给你一个尽可能大的“你好”,而不会水平溢出(在一个单词的情况下)或在一个句子或一组单词的情况下跳转到第二行?
我想不出一种方法来测量文本占用的空间,以便随后可以对照父容器的空间来检查它,更不用说检查元素是否溢出或跳线了。
如果有办法,我相信这是正确的地方。
【问题讨论】:
【参考方案1】:new jsFiddle Demo(更新 3/22/13)
我会一直增加字体大小,直到 clientWidth 或 clientHeight 改变。但是,当使用实际元素本身时,这变得不可靠。为了处理这种情况,可以动态创建跨度,然后监控跨度的尺寸,以便正确保留实际元素的原始尺寸。
js
var adjuster = document.getElementById("adjust");
adjuster.onclick = function()
var p = document.getElementById("p");
var text = p.innerText;
var s = document.createElement("span");
s.innerText = text;
p.innerhtml = "";
p.appendChild(s);
var h = p.clientHeight;
var w = p.clientWidth;
var size = 10;
while(true)
size++;
s.style.fontSize = size + "px";
if($(s).height() > h || $(s).width() > w)
size-=2;//rollback to no height change
s.style.fontSize = size + "px";
break;
p.style.fontSize = s.style.fontSize;
p.removeChild(s);
p.innerText = text;
;
【讨论】:
@AaronBlenkush - 您是否单击按钮查看它的实际效果?您使用的是什么平台。 我点击了按钮,但没有看到任何变化。我使用的是最新的普通版 Chrome(版本 26.0.1410.33 beta-m)。 @AaronBlenkush - 抱歉,您没有注意到字体发生了变化,您希望我输入警报以显示确切的变化吗?在不改变元素位置的情况下,只有轻微的变化,我相信在问题的约束下它只有 3 px(从平均 14px 或 1em 到 17px)。 修改高度以允许文本的字体大小在强制/更改高度或宽度之前变大...没有结果 @Sotkra - 这是因为我的设计读取高度和宽度的方式存在根本缺陷。不幸的是,宽度没有被正确识别,因为溢出允许它接近无穷大(如锁定)。然而!我已经修复了这个缺陷,现在有了这个相当酷的演示:jsfiddle.net/vHGBF/1。我会发布更新。【参考方案2】:又快又脏
fiddle
将p
的样式设置为display: inline
然后运行这个
var dWidth = $("div").width();
var pWidth = $("p").width();
var starting = 1;
while (pWidth < dWidth)
$("p").css("font-size",starting+"em");
pWidth = $("p").width();
starting = starting + .1;
【讨论】:
您是否愿意详细说明您的方法相对于之前发布的其他方法的优缺点? @Sotkra:它使用 em 与 px 或 pt。它需要对原始要求进行最少的 css 更改。它不涉及您必须学习如何使用的新库。 我们可以通过聊天讨论这个吗?我有很多问题会溢出这个 cmets 部分。 ?我的意思是我们通过聊天或Skype或其他方式交谈 让我们continue this discussion in chat【参考方案3】:可能有一种方法不那么疯狂,但这应该尽可能精确。本质上,您有一个 div 用于测量其宽度并逐渐增加文本内容,直到它超过目标 div 的宽度。然后,将目标div的<p>
的字体大小更改为测量div的负1:
http://jsfiddle.net/ExplosionPIlls/VUfAw/
var $measurer = $("<div>").css(
position: 'fixed',
top: '100%'
).attr('id', 'measurer');
$measurer.append($("<p>").text($("p").text()));
$measurer.appendTo("body");
while ($measurer.width() <= $("#content").width())
$("#measurer p").css('font-size', '+=1px');
console.log($("#measurer").width());
$("#measurer p").css('font-size', '-=1px');
$("#content p").css('font-size', $("#measurer p").css('font-size'));
$measurer.remove();
【讨论】:
这会将元素的高度从 20px 更改为 54px,从而改变行高。 @TravisJ 如何在不增加高度的情况下增加字体大小? 字体大小在影响高度之前只能增加这么多(在这个例子中,由于段落元素的默认行高,我只发现了 3px 的更改空间)。如果高度不是问题,字体大小可能会变得非常大,但它会开始抵消很多其他元素。 让我们假设两种情况:a) 高度无关紧要...但是当您有多个单词甚至是一个段落时,跳线怎么办? b)高度确实很重要......你如何让它只增长到高度允许的那么大? c) 出于段落应用的目的,宽度不再是问题,而是高度,例如,您希望文本根据父级的高度调整自身大小,而不考虑宽度
@Sotkra 如果您给$measurer
设置宽度,您可以对高度执行相同的测量。我的示例使用了两个词,并表明即使保持宽度也不会换行;这就是我认为的目标。【参考方案4】:
试试这个:
Auto-size dynamic text to fill fixed size container
(function($)
$.fn.textfill = function(options)
var fontSize = options.maxFontPixels;
var ourText = $('span:visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
)(jQuery);
$(document).ready(function()
$('.jtextfill').textfill( maxFontPixels: 36 );
);
<div class='jtextfill' style='width:100px;height:50px;'>
<span>My Text Here</span>
</div>
【讨论】:
geekymonkey 插件目前已被禁用,因为 jquery 的插件页面正在进行改造。上面的代码是最新版还是旧版?【参考方案5】:看看FitText
它在 github 上也是开源的。
如果您对排版感兴趣,您可能想查看他们的另一个名为Lettering.js的项目
【讨论】:
我查看了他们的代码,但他们究竟是如何检查文本元素的宽度以便将其与其父元素的宽度进行比较? Jquery/js 能否像测量固定宽度的显示块 div 或其他任何东西一样根据其字体大小测量元素的宽度?此外,它是否可以在固定 PX 中测量(基于用户设置,基于 % 的值?)最后但并非最不重要的是,当容器具有基于 % 的值时它是否工作? Github - FitText.js 包含您可以传递给它的所有参数以及如何使用它 至于他们是如何做到的:Source Code 这是实际主要工作的扩展部分。这部分包含在一个函数调用中,该函数调用为 on resize 事件调用。他们还引入了一些花哨的参数变量,或者使用默认值。 Expanded Coded 它是否允许垂直限制检查?我不这么认为以上是关于根据其父容器检查文本元素的宽度(基于字体大小)的主要内容,如果未能解决你的问题,请参考以下文章