如何捕获div中的一行文本

我已经浏览了与此相关的类似SOpost,但没有一个涉及到我正在寻找的内容。 假设我有一些文本,我把它扔在div中,并为该div添加一些任意(甚至可能是动态的)宽度。 有没有什么方法可以在div programmaticaly中捕获和操作单独的文本行(例如,捕获然后将自己的span标记中的每一行文本换行或者这样的东西,这将使我能够操作单独的行)?

我已经能够使用等宽字体完成此操作,并且基本上首先每行创建一个跨度并且每个跨度分配相同数量的字符(使用一些额外的代码,因此单词不会被切断)但是我会喜欢用非等宽字体来做这个,这当然会引起问题,因为非monopaced字体的字符水平间距会有所不同。

var str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", container = $('
'); container.width('100px').html(str).appendTo('body');

这个输出几乎是你所期望的。 它住在这里 。 我想弄清楚的是:

  1. 是否可以在换行时自动插入换行符?

  2. DOM中是否有任何其他机制或属性可以用来操作div中的一行?

  3. 是否有另一种方法,我不能保持非等宽文本的自然流动的外观,同时能够逐行访问文本? 正如我上面所说,我用等宽文本完成了这个,但我的方法依赖于等宽文本的均匀水平间距。

其他答案的建议让我很好奇,所以我把它们放到了测试中,这就是我想出来的:

 function wrapLines($container) { // get the text from the conatiner var text = $container.text(); // split the text into words var words = text.split(' '); // wrap each word in a span and add it to a tmp var tmp = ''; tmp += '' + words.join('') + ' '; // remove the text from the container, and replace it with the wrapped words $container.html($(tmp)); // prepare the offset variable and tmp var tmp = ''; var top = null; $container.find('span').each(function(index, word) { $word = $(word); // if this is the first iteration if (top == null) { // set the top top = $word.position().top; // open the first line tmp = ''; } // if this is a new line (top is bigger then the previous word) if (top < $word.position().top) { // close the previous line and start a new one tmp += ''; // change the top top = $word.position().top; } // add the content of the word node + a space tmp += $word.text() + ' '; }); // close the last line tmp += ''; // remove the content of the conatiner, and replace it with the wrapped lines $container.html($(tmp)); } 

我添加了很多评论,但随时可以询问是否有不清楚的地方。

要查看代码的实际效果(包括一些奇特的颜色;-)),请看看我的小提琴: http : //jsfiddle.net/yZnp8/1/

编辑
我把@orb的代码放在我的解决方案旁边: http : //jsfiddle.net/yZnp8/5/ 。

与Chrome Inspector的快速比较表明,性能存在很大差异。 @orbs解决方案需要754毫秒和17MB,而我的解决方案需要136毫秒和14MB。

一点建议,尝试限制你的DOM操作(我在小提琴中标记它们)。 它们会降低您的代码速度,因为浏览器需要重新呈现您的页面。 我只做2 ,而你做3 + 2x number of words + 1x number of lines 。 这可能解释了速度的巨大差异。 文本越长,差异就越大。

不试图打破@orb解决方案,只是试图提供帮助并解释差异……

我认为发布我为自己的问题提出的解决方案是一个很好的想法,因为它看起来很优雅。 我没有必要在一个范围内包装每个单词 – 我只是使用了一个可见性:隐藏的测试范围,以查看该行中的下一个单词是否会导致该行在实际添加下一个之前超过容器的宽度说到线。 当我把每一行放在一起时,我将它们添加到一个数组中。 然后我通过遍历数组将每一行附加到容器。 它住在这里 (至少有一段时间)。

 /*global console, $, OO*/ /*jslint browser: true*/ (function (undefined) { "use strict"; $(window).on('load', function (event) { var str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", $container = $('
').width('200px').text(str).appendTo('body'); wrapLines($container); }); function wrapLines($container) { var text = $container.text(), words = text.split(' '), lines = [], line = $(''), tmp = $('').css('visibility', 'hidden').appendTo('body'); $container.text(""); $.each(words, function (index, word) { if (tmp.text(line.text() + " " + word).width() < $container.width()) { line.text(line.text() + " " + word); } else { lines.push(line); line.remove(); line = $(''); tmp.text(""); } }); tmp.remove(); for (var kittens = 0 ; kittens < lines.length; kittens++) { lines[kittens].appendTo($container); console.log(lines[kittens].width()); } } }());

不确定我完全理解你的问题,但是……你能够得到div的高度吗? 除以(CSS定义的)行高,你应该有文本行数。

然后,您可以通过创建包含原始文本的一部分的不可见div来检查任何给定字符/单词的位置,并执行上述技巧以找到其行。 这有帮助吗?

Bob Monteverde提供了一段非常好的代码来计算字符串宽度。 您可以使用它并开始将字符串宽度与div的实际宽度进行比较以查找单行。