javascript - 从 (line-break : normal) html

标签 javascript html css

我想知道使用 JavaScript 是否可以实现这一点。我想从以下页面中提取第三行:

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum felis elit, scelerisque id rhoncus et, hendrerit nec turpis. Phasellus eget condimentum justo. Aliquam porta, risus sed elementum hendrerit, turpis urna posuere libero, eget facilisis sem purus sed mi. Nulla pulvinar nibh quis bibendum lacinia. Aenean eu nibh pharetra, imperdiet mi eget, vehicula mauris. In hac habitasse platea dictumst. Phasellus ante enim, bibendum quis turpis a, volutpat auctor mi. Mauris scelerisque sem a ornare dignissim. Nullam in sem ac turpis aliquet dictum sit amet dignissim est.</p>

我相信我的 html 看起来像:

enter image description here

And the red underlined line is the third line, which is adjusted dynamically in the view.

我尝试了 .innerHTML.innerText 方法,但无法识别换行符。

我想是否可以以某种方式获取每行的 scrollHeight 然后使用 JavaScript,但我在互联网上没有找到任何支持方法。有什么想法吗?

Note: One can assume that he/she has access to the p element. We may proceed with a client-side JS/HTML solution.

最佳答案

我们可以执行以下操作:

  • 空格字符拆分段落文本以获得所有单词
  • 将段落文本设置为空字符串
  • 附加每个单词并测量段落的内容大小(请谨慎使用,这种测量方式会导致大量布局重新计算)
  • 当该段落的内容大小与之前的内容大小不同时,我们就知道发生了换行
  • 当我们到达第 n 行时,添加附加的单词,直到到达新行
  • 该变量是提取的字符串

即使文本很长,此解决方案也不会阻止 UI 事件。为了在此解决方案中实现这一目标,我们可以split the long-running task to smaller ones以便仍然可以处理 UI 事件。要分割它,我们可以使用setTimeout(..., 0)。以这种方式使用 setTimeout 可以推迟运行时间较短的任务。它们仅在 message queue 的最前面运行。 。只有当一个运行时间较短的任务完成时,下一个运行时间较短的任务才会被推迟到消息队列的末尾。这允许其他与 UI 相关的消息(例如单击事件监听器的回调函数)也可以运行;因此是非阻塞的。

const p = document.querySelector('p')
const texts = p.innerText.split(' ')
const textsLength = texts.length
const nthLine = 3 // The line from which you extract the string

let i = 0
let currentWord = 0
let currentLine = 0
let currentBoxHeight = 0
let nthLineText = ''

p.innerText = ''
function getNthLineText() {
  // Split the long-running tasks of measuring words to only 100 word per callback function
  for (currentWord; currentWord < (i + 1) * 100 && currentWord < textsLength; currentWord++) {
    p.innerText += ` ${texts[currentWord]}`
    
    // Paragraph box is larger? Line-break occurred
    if (p.scrollHeight > currentBoxHeight) {
      currentBoxHeight = p.scrollHeight
      currentLine += 1
    }
    
    // We're at the nth line we want to extract, add the appended word to the result variable
    if (currentLine === nthLine) {
      nthLineText += ` ${texts[currentWord]}`
    }
  }
  
  if (currentLine > nthLine || currentWord >= textsLength) {
    console.log(`String extracted: ${nthLineText === '' ? 'None extracted' : nthLineText}`)
    p.innerText = texts.join(' ')
  } else {
    setTimeout(getNthLineText, 0)
  }
}

getNthLineText()
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum felis elit, scelerisque id rhoncus et, hendrerit nec turpis. Phasellus eget condimentum justo. Aliquam porta, risus sed elementum hendrerit, turpis urna posuere libero, eget facilisis sem purus sed mi. Nulla pulvinar nibh quis bibendum lacinia. Aenean eu nibh pharetra, imperdiet mi eget, vehicula mauris. In hac habitasse platea dictumst. Phasellus ante enim, bibendum quis turpis a, volutpat auctor mi. Mauris scelerisque sem a ornare dignissim. Nullam in sem ac turpis aliquet dictum sit amet dignissim est.</p>

关于javascript - 从 (line-break : normal) html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61038593/

相关文章:

javascript - 用于两个不同文本区域的两个复制按钮

javascript - 如何在 JavaScript 中操作数组的值?

javascript - 成本分配器 JavaScript 应用程序

javascript - 按计划/Cron 运行 PHP/Javascript/AJAX 应用程序?

javascript - 少读按钮滚动页面

java - 使用 Spring 将数据从 Thymeleaf 传递到 Controller

html - 根据 flex 子项数确定布局?

javascript - 更改无限运行 CSS 动画的当前百分比

html - 自定义复选框适用于 Chrome 和 Safari 但不适用于 Firefox 和 IE

javascript - ngAnimate 以非固定高度向下/向上滑动