我可以将每一行多行文本包装在一个跨度中吗? [英] Can I wrap each line of multi-line text in a span?

查看:16
本文介绍了我可以将每一行多行文本包装在一个跨度中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图弄清楚如何做到这一点(如果有可能的话)并且画了一个空白......

我有一些文本会换行到多行.我想检测每一行,并将其包裹在一个跨度中.最后,我想为循环数组中的每个跨度分配一个类.

例如……!

我有一些文字绕成三行在这个容器中

我想让我的 jQuery 解析这些行,检测它的换行位置,然后把它变成这样:

<span class="red-bg">我有一些文本</span><span class="orange-bg">换行到三行</span><span class="yellow-bg">在这个容器中</span>

我想动态执行此操作的原因是我在响应式模板中执行此操作,因此有时相同的文本只会换行到两行,或者在 iPhone 中可能会换行四行.

这可行吗?我找到了这个 -> http://vidasp.net/tinydemos/numberOfLines.html它计算文本块中使用的行数,但这并没有真正扩展到我需要的.

解决方案

您似乎在问如何拆分浏览器自然包裹的文本.不幸的是,这根本不是直截了当的.它也不是健壮的——考虑以下场景:

  • 用户浏览到您的页面,呈现 div 并触发 onload 事件,
  • 从文本节点创建 3 个 span 元素,每行文本换行 1 个,
  • 用户调整浏览器大小,div 的大小发生变化.

结果是跨度不再与行开始和结束的位置相关.当然,这种情况可以使用固定宽度的元素来避免,或者您可以在浏览器调整大小时重新调整整个内容,但这只是它可能会中断的一个示例.

不过,这并不容易.类似问题 之前出现过(尽管目标不同)并且出现了两种解决方案,这两种解决方案都可能对这里有所帮助:

解决方案 1:getClientRects()

实际上不要将文本包裹在 span 中,而是使用 getClientRects() 获取每行文本的位置和尺寸.然后,创建必要的跨度数并在每行文本后面定位/调整它们的大小.

优点

  • 快速;getClientRects 返回每一行的位置
  • 简单;代码比解决方案2更优雅

缺点

  • 换行文本必须包含在行内元素中.
  • 没有样式实际上适用于文本(如字体粗细或字体颜色).仅对背景颜色或边框等有用.

提供的演示与答案显示了如何突出显示当前鼠标下方的文本行.

解决方案 2:拆分、连接、循环、合并

使用 split() 方法将文本拆分为数组,并以单词边界或空格作为传递的参数.用 </span><span> 在每个元素之间将数组重新加入一个字符串,并用 ,并将原始文本节点替换为包含元素中的结果 HTML.现在,遍历每个 span 元素,检查其在容器中的 y 位置.当 y 位置增加时,你知道你已经到了一个新行,之前的元素可以合并成一个跨度.

优点

  • 每一行都可以使用任何 CSS 属性设置样式,例如 font-weight 或 text-decoration.
  • 每一行都可以有自己的事件处理程序.

缺点

  • 由于大量的 DOM 和字符串操作,速度缓慢且笨拙

结论

可能还有其他方法可以实现您的目标,但我自己也不确定.TextNode.splitText(n) 当传递要拆分的字符的数字索引时,可以将 TextNode 拆分成双胞胎 (!).上述两种解决方案都不是完美的,并且在包含元素调整大小时都会中断.

I've been trying to figure out how to do this (if it's even possible) and have drawn a blank...

I have some text that will wrap onto multiple lines. I want to detect each individual line, and wrap it in a span. Finally, I want to assign a class to each span from a looping array.

For example...!

<div id="quote">
    I have some text that
    wraps onto three lines
    in this container
</div>

I want to get my jQuery to parse those lines, detect where it wraps, and turn it into this:

<div id="quote">
    <span class="red-bg">I have some text that</span>
    <span class="orange-bg">wraps onto three lines</span>
    <span class="yellow-bg">in this container</span>
</div>

The reason that I want to do this dynamically is that I'm doing it within responsive templates, so sometimes the same text will only wrap onto two lines, or maybe four in an iPhone.

Is this doable? I've found this -> http://vidasp.net/tinydemos/numberOfLines.html which calculates the number of lines used in a block of text, but that doesn't really extend to do what I need.

解决方案

It seems like you're asking how to split the text where it is naturally wrapped by the browser. Unfortunately, this isn't straightforward at all. Neither is it robust — consider the following scenario:

  • User browses to your page, the div is rendered and the onload event fires,
  • 3 span elements are created from the text node, 1 for each wrapped line of text,
  • The user resizes the browser and the size of the div changes.

The result is that the spans no longer correlate to where the lines start and finish. Of course, this scenario is avoidable using fixed-width elements or you can rejig the whole thing when the browser resizes, but that's just an example of how it can break.

Still, it's not easy. A similar question has come up before (albeit, with a different goal) and two solutions appeared, which could both be of help here:

Solution 1: getClientRects()

Don't actually wrap the text in spans, but get the position and dimensions of each line of text using getClientRects(). Then, create the number of spans necessary and position/resize them behind each line of text.

Pros

  • Fast; getClientRects returns the position of each line
  • Simple; the code is more elegant than solution 2

Cons

  • Wrapped text must be contained by an inline element.
  • No styling will actually apply to the text (like font-weight or font-color). Only useful for things like background-color or border.

The demo provided with the answer shows how you can highlight the line of text currently beneath the mouse.

Solution 2: Split, join, loop, merge

Split the text into an array using the split() method with a word boundary or white-space as the argument passed. Rejoin the array into a string with </span><span> between each element and wrap the whole thing with <span> and </span>, and replace the original text node with the resulting HTML in the containing element. Now, iterate over each of those span elements checking its y position within the container. When the y position increases, you know that you've reached a new line and the previous elements can be merged into a single span.

Pros

  • Each line can be styled with any CSS property, like font-weight or text-decoration.
  • Each line can have its own event handlers.

Cons

  • Slow and unwieldy due to the numerous DOM and string operations

Conclusion

There may be other ways to achieve your goal, but I'm not sure of any myself. TextNode.splitText(n) can split a TextNode in twain (!) when passed a numeric index of the character you want to split on. Neither of the above solutions are perfect, and both break as soon as the containing element resizes.

这篇关于我可以将每一行多行文本包装在一个跨度中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆