javascript - 如何将附加文本放入其容器内

标签 javascript html css

我想将一个段落附加到页面,并为该段落的每个单词添加一个特定的 id (我将每个单词用 span 包裹在 id 中,以便我们稍后可以控制每个单词的颜色)

代码工作正常,但有一个问题我无法手动解决。

我想要的最大字体大小为5vw我想减小字体大小,以便将整个段落放入 paragraphContainer 中。

我已经尽力了,但不幸的是,这还不够!

使用let fontSize = getFontSize(paragraphOriginal);我试图获取多行附加文本的高度,但我认为它只需要单行的高度!如果我能得到多行的高度...

这是代码:

// our paragraph
let paragraphOriginal = "During a discussion that popped up over this, Adam pointed out there is a new CSS property that is (as I understand it) specifically for this. This removes the need for three elements. Technically you only need one, the inline element, but it's likely you'll be doing this on a header so you'll probably end up with a block-parent anyway, which is best for spacing. LAST WORDS";

// Convert above paragraph to array of words
let paragraphWords = paragraphOriginal.replace(/\s+/g, " ").toLowerCase().replace(/\,|\?|\!|\:|\./g, '').trim().split(' ');


//dimensions of the paragraphContainer container
let height = document.getElementsByClassName("paragraphContainer")[0].clientHeight;

let text_Height;


// Add paragraph to page and assign each word an specific id 
generateParagraph();


function generateParagraph() {

  let paragraph = document.getElementById("paragraph");
  let answerPrototype = '';

  for (let i = 0; i < paragraphWords.length; i++) {
    paragraphWords[i] = ' ' + paragraphWords[i];
  }
  //paragraphWords[0] = paragraphWords[0].trim();

  let paragraphSpans = '';

  for (let i = 0; i < paragraphWords.length; i++) {

    paragraphSpans += `<span class='spans' id='spanID${i}'>${paragraphWords[i]}</span>`;

  };

  //modify the font size based on text length

  let fontSize = getFontSize(paragraphOriginal); // I think here is the problem

  console.log(fontSize);

  paragraph.style.fontSize = `${fontSize}vw`;

  paragraph.innerHTML = `${paragraphSpans}`;

};




function getFontSize(paragraph) {

  let default_size = 5;

  do {
    default_size -= 0.1;
    text_Height = getTextHeight(paragraph, `bold ${default_size}vw Open Sans`);
  }

  while (text_Height > height);

  return default_size.toFixed(2);

};


//Start Of Text Height Function
function getTextHeight(text, font) {
  let canvas = document.createElement("canvas")
  let context = canvas.getContext("2d");

  let sourceWidth = canvas.width;
  let sourceHeight = canvas.height;

  context.font = font;

  // place the text somewhere
  context.textAlign = "left";
  context.textBaseline = "top";
  context.fillText(text, 25, 5);

  // returns an array containing the sum of all pixels in a canvas
  // * 4 (red, green, blue, alpha)
  // [pixel1Red, pixel1Green, pixel1Blue, pixel1Alpha, pixel2Red ...]
  let data = context.getImageData(0, 0, sourceWidth, sourceHeight).data;

  let firstY = -1;
  let lastY = -1;

  // loop through each row
  for (let y = 0; y < sourceHeight; y++) {
    // loop through each column
    for (let x = 0; x < sourceWidth; x++) {
      //var red = data[((sourceWidth * y) + x) * 4];
      //var green = data[((sourceWidth * y) + x) * 4 + 1];
      //var blue = data[((sourceWidth * y) + x) * 4 + 2];
      let alpha = data[((sourceWidth * y) + x) * 4 + 3];

      if (alpha > 0) {
        firstY = y;
        // exit the loop
        break;
      }
    }
    if (firstY >= 0) {
      // exit the loop
      break;
    }

  }

  // loop through each row, this time beginning from the last row
  for (let y = sourceHeight; y > 0; y--) {
    // loop through each column
    for (let x = 0; x < sourceWidth; x++) {
      var alpha = data[((sourceWidth * y) + x) * 4 + 3];
      if (alpha > 0) {
        lastY = y;
        // exit the loop
        break;
      }
    }
    if (lastY >= 0) {
      // exit the loop
      break;
    }

  }

  return lastY - firstY;

}; //End Of Text Height Function
html {
  overflow: hidden;
  background-color: transparent;
}

.paragraphContainer {
  position: absolute;
  overflow: hidden;
  left: 2.45vw;
  top: 25vh;
  height: 55vh;
  width: 95vw;
  outline: 0.1vw dashed orange;
}

.paragraph-class {
  position: absolute;
  white-space: pre-wrap;
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
  color: #595959;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  padding: 0vh 1vh 20vh 1vh;
  justify-content: left;
  align-items: left;
}
<!DOCTYPE html>
<html>

<head>

  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&display=swap" rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="style.css">

</head>

<body>

  <div class="paragraphContainer">
    <div id="paragraph" class="paragraph-class"></div>
  </div>


  <!-- <button id="myBtn">Try it</button>

<script>
document.getElementById("myBtn").addEventListener("click", function(){
  Read();
});
</script> -->


  <script src="script.js"></script>
</body>

</html>

最佳答案

我已尽力为您找到解决方法,因此我将解释我所做的事情,希望它有所帮助。

首先,我删除了 getFontSize(paragraph)getTextHeight(text, font) 因为它们每次都会返回相同的字体大小,而不管文本高度和删除了一些无用的 CSS 规则。

接下来,我添加了 scaleFontVW() 函数,在其中缩放每个 font-sizeline-height span 因为您需要同时执行这两项操作。

接下来,while(paragraph.scrollHeight > paragraphContainer.clientHeight)基本上我将溢出的内容高度与容器的高度进行比较,并循环直到两者变为一。

接下来,通过减去 fontSize 的值来缩小每个跨度大小(通过反复试验,我发现 5 效果很好),以及 line-height段落的行高公式也非常简单:font-size + font-size * 20%

有帮助的答案:Paul'smicnic's

// our paragraph
let paragraphOriginal = "During a discussion that popped up over this, Adam pointed out there is a new CSS property that is (as I understand it) specifically for this. This removes the need for three elements. Technically you only need one, the inline element, but it's likely you'll be doing this on a header so you'll probably end up with a block-parent anyway, which is best for spacing. LAST WORDS";



// Convert above paragraph to array of words
let paragraphWords = paragraphOriginal.replace(/\s+/g, " ").toLowerCase().replace(/\,|\?|\!|\:|\./g,'').trim().split(' ');


//dimensions of the paragraphContainer container
let height = document.getElementsByClassName("paragraphContainer")[0].clientHeight;

let text_Height;


// Add paragraph to page and assign each word an specific id 
generateParagraph();

// Scale the font to fit
scaleFontVW();

function generateParagraph() {

    let paragraph = document.getElementById("paragraph");
    let answerPrototype = '';

    for(let i = 0; i < paragraphWords.length; i++){
        paragraphWords[i] = ' ' + paragraphWords[i];
    }
    //paragraphWords[0] = paragraphWords[0].trim();

    let paragraphSpans = '';

    for (let i = 0; i < paragraphWords.length; i++) {

      paragraphSpans += `<span class='spans' id='spanID${i}'>${paragraphWords[i]}</span>`;

    };

    //modify the font size based on text length

    //let fontSize = getFontSize(paragraphOriginal ); // I think here is the problem

    //console.log(fontSize);
    
    //paragraph.style.fontSize = `${fontSize}vw`;
     
    paragraph.innerHTML = `${paragraphSpans}`;

};

function scaleFontVW() {
  let paragraph = document.getElementById("paragraph");
  let paragraphContainer = document.getElementById("pc")
  let spans = document.getElementsByTagName("span");

  let style = window.getComputedStyle(spans[0], null).getPropertyValue('font-size');
  let fontSize = parseFloat(style); 

  while(paragraph.scrollHeight >= paragraphContainer.clientHeight) {
    fontSize -= 5;
    for(let i = 0; i < spans.length; i++) {
      spans[i].style.fontSize = fontSize+"px";
      }
    paragraph.style.lineHeight = fontSize*0.2 + fontSize + "px";
}
}

function scaleFontVW_2() {
  let paragraph = document.getElementById("paragraph");
  let paragraphContainer = document.getElementById("pc")

  let style = window.getComputedStyle(spans[0], null).getPropertyValue('font-size');
  let fontSize = parseFloat(style); 

  while(paragraph.scrollHeight >= paragraphContainer.clientHeight) {
    fontSize -= 1;
    paragraph.style.fontSize = fontSize+"px";
    paragraph.style.lineHeight = fontSize*0.2 + fontSize + "px";
}
}
html{
  background-color: transparent;
}

.paragraphContainer {
    position: absolute;
    left: 2.45vw;
    top: 25vh;
    height: 55vh;
    width: 95vw;   
    outline: 0.1vw dashed orange;
}

.paragraph-class {
    font-size: 5vw;
    position: absolute;
    white-space: pre-wrap; 
    font-family: 'Open Sans', sans-serif;  
    font-weight:400;
    color: #595959;
}
<!DOCTYPE html>
<html>
<head>

  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&display=swap" rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="style.css"> 

</head>

<body> 

<div id = "pc" class="paragraphContainer"> 
<div id="paragraph" class="paragraph-class"></div>
</div>


<!-- <button id="myBtn">Try it</button>

<script>
document.getElementById("myBtn").addEventListener("click", function(){
  Read();
});
</script> -->


<script src="script.js"></script>
</body>

</html>

关于javascript - 如何将附加文本放入其容器内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60514117/

相关文章:

css - Safari Webkit 动画(旋转)不工作

CSS - IE8 错误

javascript - 如何检索配置文件的所有位置,包括过去的位置

javascript - 如何在3个按钮后显示 "read more"链接

javascript - 用 twig 删除 img 字段中的 onerror 标签

javascript - 为什么 outerHTML 会带回 &lt;!- - --> 评论?

jquery - 如何在单击 HTML 图像映射时切换回原始状态

javascript - rxjs 订阅 onerror 绑定(bind)

javascript - 使用处理函数更改 html 页面

javascript - 将 .txt 而不是图像文件加载到 jquery 中