如何捕获div中的一行文本

orb*_*orb 7 html javascript css jquery

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

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

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 = $('<div>');
    container.width('100px').html(str).appendTo('body');
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Pev*_*ara 6

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

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 += '<span>' + words.join('</span><span>') + '</span> ';

   // 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 = '<span class="line">';
        }

        // 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 += '</span><span class="line">';
            // change the top
            top = $word.position().top;            
        }

        // add the content of the word node + a space
        tmp += $word.text() + ' ';
    });
    // close the last line
    tmp += '</span>';

    // remove the content of the conatiner, and replace it with the wrapped lines
    $container.html($(tmp));    
}
Run Code Online (Sandbox Code Playgroud)

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

要查看代码(包括一些奇特的颜色;-)),请看看我的小提琴: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解决方案,只是试图提供帮助并解释差异......