如何为内容不断被替换的段落设置字体大小

Posted

技术标签:

【中文标题】如何为内容不断被替换的段落设置字体大小【英文标题】:How to set font size for a paragraph whose content is being constantly replaced 【发布时间】:2018-09-24 20:45:13 【问题描述】:

我想设置一个带有段落的框。每次单击按钮后,都应该替换本段的文本。对我来说重要的是这个文本应该作为一行留在框中,而不是中断。为此,我决定使用 FitText.js 插件,因为单词有不同的长度(给定的单词只是一个例子)。通过将其设置为表格和表格单元格,我实现了很好的对齐(垂直和水平)。你知道为什么给定的代码不能正常工作吗?

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array)
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];

   
function function1()
    var randomWord = getRandomItem(words); 
    document.getElementById('word').innerhtml = randomWord;


$('#give_me_a_name_please').click(function()  
    function resize ()  $("#word").fitText(0.6);  
);
#parent_of_word 
  width: 20%;
  height: 20%;
  top: 10%;
  left: 10%;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  word-break: keep-all;
  white-space: nowrap;


#word 
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_word">
    <p id="word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

【问题讨论】:

你忘了问一个编程问题,@wymy...不清楚你在问什么。 我会编辑它。 @wyzy,您刚刚更改了您的问题以包含我回答的重要部分。你不应该那样做。您只能进行修改,以便清楚您的问题是什么,并保持清晰,以便对其他未来的访问者有所帮助。 @wymyszony 您希望框扩大以适合文本还是文本应调整并适合框? 文本应该调整并适合框。 【参考方案1】:

编辑:用更优化的循环更新了代码 sn-p 和 JSFiddle。

我已对您的示例代码进行了调整,使其更精简且更易于理解。它还使用纯 jQuery 而不是 jQuery 和纯 JS 的混合,并且在多次按下按钮后不会停在“未定义”处,从而导致一个空数组。相反,它会再次循环遍历所有单词。

这里有两个主要的解决方案。

人们从javascript Scale Text to Fit in Fixed Div 的这种迭代方法中获得灵感,其中字体大小从一个固定值开始,然后根据需要缩小,直到单词的宽度小于其容器的宽度。不需要插件,因为这非常简单。 第二部分实现了overflow:hidden,这样如果文本太大以至于无法缩小到足够小(参见while循环中的下限8),它仍然不会脱离它的容器。

另见the JSFiddle version。

var words = [
  "Emily",
  "William Callum Smith Jr.",
  "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard",
  "EdwaaaaaaaaaaaaaaaaaaaAAAAAAAAAaaaaaAAaaaaAAAaaaaaaaaaaaaaaaaaaaaaaaaard",
  "Bradley",
  "The quick brown fox"
];

var changeWord = $("#change_word");
var parentOfWord = $("#parent_of_word");
var word = $("#word");
var idx = 0;

changeWord.click(function() 
  word.text(words[idx++ % words.length]);
  var size = 40;
  word.css("font-size", size);
  while (word.width() > parentOfWord.width() && size > 8) 
    word.css("font-size", --size);
  
);
#parent_of_word 
  width: 200px;
  height: 50%;
  top: 50px;
  left: 50%;
  margin-left: -100px;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  word-break: keep-all;
  white-space: nowrap;
  overflow: hidden;


#word 
  color: brown;
  display: flex;
  align-items: center;
  justify-content: center;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>
  <button id="change_word">Button</button>
</p>
<div id="parent_of_word">
  <p id="word">----------------</p>
</div>

【讨论】:

"...纯 jQuery 而不是 jQuery 和纯 JavaScript 的混合"?你让我开心! 哈哈...是的,这听起来很有趣。希望这是有道理的。【参考方案2】:

将您的文本放在一行中,而不中断:

white-space: nowrap;

垂直和水平居中:

display:flex;
align-items: center;
justify-content: center;

应用于您的示例:

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Resize this to see how it behaves on narrower screens. Lorem ipsum dolor sit amet bla bla bla, lorem ipsum dolor sit amet bla bla bla, lorem ipsum dolor sit amet bla bla bla.", "Bradley"];


var button1 = document.getElementById("give_me_a_name_please");


button1.addEventListener("click", function1);

function getRandomItem(array)
  return array.splice(Math.floor(Math.random() * array.length), 1)[0];

   
function function1()
var randomWord = getRandomItem(words) || 'No more options.'; 
document.getElementById('word').innerHTML = randomWord;


$( '#give_me_a_name_please' ).click(function()  
function resize ()  $("#word").fitText(0.6); 
 
);
#parent_of_word 
  display: flex;
  align-items: center;
  justify-content: center;
  /* rest optional, just to demo 
  * vertical alignment 
  */  
  height: calc(100vh - 40px); 
  border: 1px solid red;
  padding: 1rem;


#word 
  white-space: nowrap;
  border: 5px solid;
  padding: 1rem;
  flex: 0 1 auto;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;

 * 
  margin: 0;
  box-sizing: border-box;
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_word">
<p id="word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

【讨论】:

【参考方案3】:

因为你定义了#parent_of_wordwidth20%,这当然和它的父元素有关,即body 元素,基于给定的示例。

所以#parent_of_wordwidth 不能仅仅根据其内容的宽度动态调整大小。它只能“在视觉上调整大小”连同它的父宽度,但仍然需要20%。即使使用的单位是% 并且元素的宽度动态,它仍然是固定的。

所以我的解决方案是省略width 属性,只定义您选择的padding

注意:我已经把不必要的注释掉了。

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array) 
  return array.splice(Math.floor(Math.random() * array.length), 1)[0];

   
function function1() 
  var randomWord = getRandomItem(words); 
  document.getElementById('word').innerHTML = randomWord;


$('#give_me_a_name_please').click(function() 
  function resize() 
    $("#word").fitText(0.6); 
   
);
#parent_of_word 
  display: flex;
  /*width: 20%; the culprit*/
  height: 20%;
  padding: 0 20px; /* can also use [%] */
  position: absolute;
  top: 10%;
  left: 10%;
  /*text-align: center;*/
  justify-content: center;
  align-items: center; /* added; vertical alignment */
  /*line-height: 100%;*/
  border: 5px solid black;
  /*
  word-break: keep-all;
  white-space: nowrap;
  */
  color: brown;


/*
#word 
  color: brown;
  display: flex;
  align-items: center;
  justify-content: center;

*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>

<button id="give_me_a_name_please">Button</button>

<div id="parent_of_word">
  <p id="word">----------------</p>
</div>

【讨论】:

【参考方案4】:

解决问题的最简单方法是将#parent_of_word 的宽度值更改为width:auto。这将根据内容自动调整宽度(根据段落长度自动调整)。

工作示例:https://jsfiddle.net/18faLbap/4/

【讨论】:

除了doesn't really work。如果文本过多或空间过小,则会自动换行。 它工作得很好,但我没有提到我的盒子的宽度必须固定。例如屏幕的 20%。 如果文本输入大于屏幕的 20% 怎么办?它要么必须离开容器 div 要么包装。你能动态改变文本的字体大小吗?如果是这样,如果您希望 div 仅占据屏幕的 20% 并避免换行,那么这确实是您唯一的解决方案。 这就是我想要实现的。根据我的段落长度动态改变字体大小。【参考方案5】:

当我想将文本保持在一行时,我通常会采用这种方法。特别是我的网格。 因此,无论您的框有多长,它都会排成一行,当您将鼠标悬停在其上时,它会逐行排列以便于阅读。

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array)
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];

   
function function1()
    var randomWord = getRandomItem(words); 
    document.getElementById('word').innerHTML = randomWord;


$('#give_me_a_name_please').click(function()  
    function resize ()  $("#word").fitText(0.6);  
);
#parent_of_word 
  width: 20%;
  
  top: 10%;
  left: 10%;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  word-break: keep-all;



#word 
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;


#word:hover 
    white-space: normal;
    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_word">
    <p id="word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

【讨论】:

【参考方案6】:
#parent_of_word 
    min-width: 20%;
    width: auto;
    padding: 0px 20px;

我在这里所做的只是添加width: auto 并设置min-width:20%。当文本在框内更新时,这会使宽度动态化。添加了一点padding 让它看起来也不错。希望这会有所帮助。

【讨论】:

【参考方案7】:

既然页面上已经有 jQuery,请考虑使用 jquery-textfill 插件:

http://jquery-textfill.github.io/

它将确保您的文本适合您的容器。

【讨论】:

【参考方案8】:

有一种 CSS 方法可以在内容中适应单词

我基本上禁用了#parent_of_word 的绝对宽度并将display 更改为inline-block,以便其宽度适合其内容。为了让它更漂亮,我添加了padding 属性。您的代码的简化和改进版本如下所示。

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array)
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];

   
function function1()
    var randomWord = getRandomItem(words); 
    document.getElementById('word').innerHTML = randomWord;
#parent_of_word 
  top: 10%;
  left: 10%;
  display: inline-block;
  position: absolute;
  text-align: center;
  padding: 10px;
  border: 5px solid black;
  word-break: keep-all;


#word 
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;


#word:hover 
    white-space: normal;
    
<div id="parent_of_word">
    <p id="word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

所以您现在不再需要额外的 JavaScript 库。更多知识可以找here

【讨论】:

以上是关于如何为内容不断被替换的段落设置字体大小的主要内容,如果未能解决你的问题,请参考以下文章

如何为整个应用程序创建字体大小选项(小、正常、大)? [复制]

CSS:如何为每种字体设置不同的大小

如何为 NSButton 的标题设置自定义颜色和字体大小?(在 OS X 而非 iOS 中)[重复]

python-docx对替换后的文字设置英文字体中文字体字号大小对齐方式

如何为 UILabel 字体更改设置动画?

spiredoc设置段落字体大小