【问题标题】:jQuery text truncation (read more style)jQuery 文本截断(阅读更多样式)
【发布时间】:2011-01-15 23:09:52
【问题描述】:

我的问题与“Trim text to 340 chars”非常相似,但在 jQuery 中。这听起来很直接,但当我四处搜索时,我找不到任何参考。

好的,我有一个 div $('#content') 我想将文本修剪为“x”个字符,比如说“600”但是我不希望它自己破坏这个词!就像不是“The Ques...”而是“The Questions...”。

剩下的文字会怎样?好吧,我把它隐藏起来,并会根据要求显示!但是等等,它应该首先删除 '...' 并在它隐藏的地方显示文本。

这是 $('#content') 的示例结构:

<div id="content">
    <p>Once upon a midnight dreary, while I pondered weak and weary,Over many a quaint and curious volume of forgotten lore.</p>
    <p>Writing example text is very boring.</p>
    <p>Specially when you are dumb enough not to copy and paste. Oh!</p>
    <p>Once it sheltered the rogues and rapscallions of the British Empire; now Kangaroo Island is ready and waiting for some derring-do of your own. Venture into the rugged wilds of the island, traversing untamed bushland and pristine beaches seeking out seal, penguin and sea lion colonies. Meet the land loving locals - koalas, goannas, echidnas and the island's own species of kangaroo. </p>
</div>

应该如何加载:

曾几何时,一个沉闷的午夜,而我 思索着虚弱和疲倦,经历了许多 古朴而好奇的被遗忘的卷 知识。

编写示例文本是... [阅读 更多]

点击“阅读更多”后:

曾几何时,一个沉闷的午夜,而我 思索着虚弱和疲倦,经历了许多 古朴而好奇的被遗忘的卷 传说。

编写示例文本很无聊。

特别是当你足够愚蠢的时候 复制和粘贴。哦!

一旦它庇护了流氓和 大英帝国的喧嚣; 现在袋鼠岛准备好了 等待你的一些错误行为 自己的。冒险进入崎岖的荒野 岛屿,穿越野蛮 丛林和原始海滩寻求 出海豹、企鹅和海狮 群落。认识热爱土地的当地人 - 考拉、巨蜥、针鼹和岛上的袋鼠。


更新: 我发现这两个插件与这个最佳答案基本相同。然而,最好的答案有一些这些插件没有的功能,反之亦然!

【问题讨论】:

    标签: jquery text trim


    【解决方案1】:

    如果您不介意丢失段落标签,以下内容可用于限制文本数量。

    <script type="text/javascript">
    var shortText = $("#content").text()    // get the text within the div
        .trim()    // remove leading and trailing spaces
        .substring(0, 600)    // get first 600 characters
        .split(" ") // separate characters into an array of words
        .slice(0, -1)    // remove the last full or partial word
        .join(" ") + "..."; // combine into a single string and append "..."
    </script>
    

    【讨论】:

    • @Tim: split().slice().join()trim().substring(0, lastIndexOf(' ')) 快吗?
    • @Mendy 好点。 lastIndexOf 应该更快,因为整个字符串的迭代次数更少。
    【解决方案2】:

    此代码假定标签将始终保持平衡,并且唯一没有关闭符的标签将是 &lt;br /&gt;(尽管如果需要,这很容易解决)。

    #content {
        width: 800px;
        clear:both;
        clip:auto;
        overflow: hidden;
    }
    .revealText {
        background: white; /* Strange problem in ie8 where the sliding animation goes too far
                                if revealText doesn't have a background color!  */
    }
    .hiddenText {
    
    }
    .readMore {
        cursor: pointer;
        color: blue;
    }
    .ellipsis {
        color: black;
    }
    
    $('document').ready(function() {
    
    truncate('#content');
    
    $('.readMore').on('click', function() {
        var $hidden = $('.hiddenText');
        if($hidden.is(':hidden')) {
            $hidden.show();
            $(this).insertAfter($('#content')).children('.readMoreText').text(' [Read Less] ').siblings().hide();
        } else {
            $(this).appendTo($('.revealText')).children('.readMoreText').text(' [Read More] ').siblings().show();
            $hidden.hide();
        }
    });
    
    $('.readMore').click();
    
    function truncate(element) {
        $(element + ' p').css({display: 'inline'});
    
        var theText = $(element).html();        // Original Text
        var item;                               // Current tag or text area being iterated
        var convertedText = '<span class="revealText">';    // String that will represent the finished result
        var limit = 154;                        // Max characters (though last word is retained in full)
        var counter = 0;                        // Track how far we've come (compared to limit)
        var lastTag;                            // Hold a reference to the last opening tag
        var lastOpenTags = [];                  // Stores an array of all opening tags (they get removed as tags are closed)
        var nowHiding = false;                  // Flag to set to show that we're now in the hiding phase
    
        theText = theText.replace(/[\s\n\r]{2,}/g, ' ');            // Consolidate multiple white-space characters down to one. (Otherwise the counter will count each of them.)
        theText = theText.replace(/(<[^<>]+>)/g,'|*|SPLITTER|*|$1|*|SPLITTER|*|');                      // Find all tags, and add a splitter to either side of them.
        theText = theText.replace(/(\|\*\|SPLITTER\|\*\|)(\s*)\|\*\|SPLITTER\|\*\|/g,'$1$2');           // Find consecutive splitters, and replace with one only.
        theText = theText.replace(/^[\s\t\r]*\|\*\|SPLITTER\|\*\||\|\*\|SPLITTER\|\*\|[\s\t\r]*$/g,''); // Get rid of unnecessary splitter (if any) at beginning and end.
        theText = theText.split(/\|\*\|SPLITTER\|\*\|/);            // Split theText where there's a splitter. Now we have an array of tags and words.
    
        for(var i in theText) {                                     // Iterate over the array of tags and words.
            item = theText[i];                                      // Store current iteration in a variable (for convenience)
            lastTag = lastOpenTags[lastOpenTags.length - 1];        // Store last opening tag in a variable (for convenience)
            if( !item.match(/<[^<>]+>/) ) {                         // If 'item' is not a tag, we have text
                if(lastTag && item.charAt(0) == ' ' && !lastTag[1].match(/span|SPAN/)) item = item.substr(1);   // Remove space from beginning of block elements (like IE does) to make results match cross browser
                if(!nowHiding) {                                        // If we haven't started hiding yet...
                    counter += item.length;                             // Add length of text to counter.
                    if(counter >= limit) {                              // If we're past the limit...
                        var length = item.length - 1;                   // Store the current item's length (minus one).
                        var position = (length) - (counter - limit);    // Get the position in the text where the limit landed.
                        while(position != length) {                     // As long as we haven't reached the end of the text...
                            if( !!item.charAt(position).match(/[\s\t\n]/) || position == length )   // Check if we have a space, or are at the end.
                                break;                                  // If so, break out of loop.
                            else position++;                            // Otherwise, increment position.
                        }
                        if(position != length) position--;
                        var closeTag = '', openTag = '';                // Initialize open and close tag for last tag.
                        if(lastTag) {                                   // If there was a last tag,
                            closeTag = '</' + lastTag[1] + '>';         // set the close tag to whatever the last tag was,
                            openTag = '<' + lastTag[1] + lastTag[2] + '>';  // and the open tag too.
                        }
                        // Create transition from revealed to hidden with the appropriate tags, and add it to our result string
                        var transition = '<span class="readMore"><span class="ellipsis">...</span><span class="readMoreText"> [Read More] </span></span>' + closeTag + '</span><span class="hiddenText">' + openTag;
                        convertedText += (position == length)   ? (item).substr(0) + transition
                                                                    : (item).substr(0,position + 1) + transition + (item).substr(position + 1).replace(/^\s/, '&nbsp;');
                        nowHiding = true;       // Now we're hiding.
                        continue;               // Break out of this iteration.
                    }
                }
            } else {                                                // Item wasn't text. It was a tag.
                if(!item.match(/<br>|<BR>/)) {                      // If it is a <br /> tag, ignore it.
                    if(!item.match(/\//)) {                         // If it is not a closing tag...
                        lastOpenTags.push(item.match(/<(\w+)(\s*[^>]*)>/));     // Store it as the most recent open tag we've found.
                    } else {                                                    // If it is a closing tag.
                        if(item.match(/<\/(\w+)>/)[1] == lastOpenTags[lastOpenTags.length - 1][1]) {    // If the closing tag is a paired match with the last opening tag...
                            lastOpenTags.pop();                                                         // ...remove the last opening tag.
                        }
                        if(item.match(/<\/[pP]>/)) {            // Check if it is a closing </p> tag
                            convertedText += ('<span class="paragraphBreak"><br> <br> </span>');    // If so, add two line breaks to form paragraph
                        }
                    }
                }
            }   
            convertedText += (item);            // Add the item to the result string.
        }
        convertedText += ('</span>');           // After iterating over all tags and text, close the hiddenText tag.
        $(element).html(convertedText);         // Update the container with the result.
    }
    });
    
    
    <div id="content">
        <p>Once upon a midnight dreary, while I pondered weak and weary,Over many a quaint and curious volume of forgotten lore.</p>
        <p>Writing example text is very boring.</p>
        <p>Specially when you are dumb enough not to copy and paste. Oh!</p>
        <p>Once it sheltered the rogues and rapscallions of the British Empire; now Kangaroo Island is ready and waiting for some derring-do of your own. Venture into the rugged wilds of the island, traversing untamed bushland and pristine beaches seeking out seal, penguin and sea lion colonies. Meet the land loving locals - koalas, goannas, echidnas and the island's own species of kangaroo. </p>
    </div>
    

    【讨论】:

    • @patrick:感谢您的回答,它并没有像我希望的那样完全发挥作用。更改不透明度将隐藏文本,但不会上下滑动页面。另外,我想弄清楚的棘手问题是,如果 100 个字符到达“

      ”标签内;当您单击查看更多时,它将删除“...”并显示原本应具有的其余内容。我希望这是有道理的。

    • @Mazzi - 我只是做了不透明度来直观地展示两半。由于它们是分开的,所以很容易向上或向下滑动隐藏的部分。我只是没有实现它。这种工作方式,它永远不会在标签中间分裂。只有 words 中的字符被添加到计数器中。计数器正好越过标签。所以这应该不是问题。
    • @Mazzi - 给你的问题。如果您希望通过上拉隐藏文本,那么当限制结束在一行中间时,您希望它如何工作?
    • @patrick:抱歉没有意识到它是故意留下的。答:这就是我不解的地方。理想情况下,如果限制到达一行的中间,则休息应替换为“...”,然后当您单击“阅读更多”时,它应删除“...”并继续其余文本 - 恰到好处它切断的地方。谢谢
    • @Mazzi - 如果脚本将&lt;p&gt; 标记替换为&lt;span&gt; 标记以及一对&lt;br /&gt; 标记来组成段落,这是否是一个可接受的解决方案?我们需要它是内联的,但是&lt;p&gt; 标签是块状的,并且你会在内联标签内使用块状标签得到意想不到的结果。
    【解决方案3】:

    嗯,有一个插件。 jQuery Expander.

    【讨论】:

    【解决方案4】:

    您可以使用 jQuery Expander Plugin 轻松做到这一点。 http://plugins.learningjquery.com/expander/index.html#download?

    【讨论】:

      猜你喜欢
      • 2013-03-29
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2016-04-27
      • 1970-01-01
      相关资源
      最近更新 更多