我想知道使用 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 看起来像:
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/