【问题标题】:How to split an HTML paragraph up into its lines of text with JavaScript如何使用 JavaScript 将 HTML 段落拆分为文本行
【发布时间】:2015-03-11 00:21:40
【问题描述】:

是否有可能(以及我如何)使用 JavaScript 将一段文本拆分为相应的行。我想做的是在段落或块引用的每一行上实现悬挂标点,而不仅仅是起始行。

也欢迎任何其他想法!

澄清我被要求不要对“将段落分成各自的行”的含义不那么含糊。

在 HTML 中,<p> 元素创建一个文本块。同样,许多其他元素也是如此。这些文本正文被包装以适应宽度(无论宽度是由 css 设置还是由默认设置假定)我似乎无法使用正则表达式或任何其他方式检测到换行符发生的位置。因此,假设一个段落最终有 7 行长,我希望能够检测到它是 7 行,以及这些行的开始和结束位置。

寻找\n\r 似乎没有任何结果。

【问题讨论】:

  • 你能解释一下你所说的悬挂标点符号是什么意思吗?这和多行省略号一样吗?
  • 当行首或行尾的标点悬在左边或右边距之外时:css-tricks.com/almanac/properties/h/hanging-punctuation
  • 题名与题体不符,题主题为“悬挂标点”(含糊不清,但肯定不同于分行)。他们都没有解释将一个段落分成几行意味着什么(一个段落可以被格式化为无限多行的行)。你应该在问题本身中明确地解释你想要什么,并可能用图像来说明它。
  • 您是否需要确切地知道它在哪里分割,或者只是行数可以吗?对于行数,您可以将段落的高度除以其行高stackoverflow.com/questions/9063178/… 要获得确切的文本位置,您必须将段落分成<span>s 并获取每个<span> 的位置跨度>
  • 啊,真聪明。行数可能会有所帮助,但最终还是要了解标点符号出现在行首还是行尾。

标签: javascript html css string


【解决方案1】:

看起来hanging-punctuation css 属性只能确保元素的第一个格式化行的开头处的任何标点符号挂起。因此,您希望将文本动态拆分为正确长度的行,将它们放入新的<p> 元素(或块引用)中并将hanging-punctuation: 'first' 应用于这些新元素。截至目前,没有主流浏览器支持 hanging-punctuation 属性 (citation)。

通常我会建议检查换行符 (\n) 在文本中的位置,但通常没有人明确地将其放在他们编写的文本中。相反,它们让浏览器根据窗口大小(类似于自动换行)决定在哪里添加新行。当您开始考虑给定的<p> 元素中可能有多行时,这会变得更加棘手,并且取决于浏览器窗口的大小,该行可以在任何地方分割。您必须抓取文本,找到它的容器的宽度,然后以某种方式查看它在文本字符串中的哪个位置达到该宽度。 Heres a great blogpost 讨论了如何在更一般的意义上实现这一点。

【讨论】:

  • 好的,是的,这也是我的想法。希望有更好的东西。
【解决方案2】:

一个蛮力的方法是拆分段落中的所有单词并制作spans。然后,您可以测量跨度的 offsetTop 属性,以找出哪些以不同的行结束。

在下面的 sn-p 中,getLines() 返回一个数组数组,其中每个内部数组是一个包含一行中每个单词的 span 元素。然后,您可以根据需要使用一些 CSS 来创建悬挂标点符号,可能通过在标点符号中插入绝对定位的跨度来操作它。

//So it runs after the animation
setTimeout(function(){
    splitLines();
    showLines();
}, 1000)

function showLines() {
  var lines = getLines();
  console.log(
    lines.map(function(line) {
      return line.map(function(span) {
        return span.innerText;
      }).join(' ')
    }));
}

function splitLines() {
  var p = document.getElementsByTagName('p')[0];
  p.innerHTML = p.innerText.split(/\s/).map(function(word) {
    return '<span>' + word + '</span>'
  }).join(' ');
}



function getLines() {
  var lines = [];
  var line;
  var p = document.getElementsByTagName('p')[0];
  var words = p.getElementsByTagName('span');
  var lastTop;
  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word.offsetTop != lastTop) {
      lastTop = word.offsetTop;
      line = [];
      lines.push(line);
    }
    line.push(word);
  }
  return lines;
}
<p>Here is a paragraph that we want to track lines for. Here is a paragraph that we want to track lines for. Here is a paragraph that we want to track lines for Here is a paragraph that we want to track lines for Here is a paragraph that we want to track
  lines for Here is a paragraph that we want to track lines for</p>

这是一个小提琴,您可以调整窗口大小,以便段落改变大小http://jsfiddle.net/4zs71pcd/1/

【讨论】:

  • 这真的很有帮助!非常感谢。也许你甚至可以在所有相关的标点符号上拆分段落,可选地添加负填充或其他东西来移动它们。但是如何判断标点是在行首还是行尾呢?
  • @Costa 如果它是getLines()返回的每个子数组中的第一项或最后一项,您可以判断它是在行首还是行尾
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多