Cutting HTML strings without breaking HTML tags

前端 未结 7 804
别跟我提以往
别跟我提以往 2021-01-04 19:34

How to write a function that can cut a string with HTML tags to an N-length string without breaking HTML tags while doing it.

The returned string doesn\'t need to b

相关标签:
7条回答
  • 2021-01-04 19:58
    function trimHtml(html, options) {
    
        options = options || {};
    
        var limit = options.limit || 100,
            preserveTags = (typeof options.preserveTags !== 'undefined') ? options.preserveTags : true,
            wordBreak = (typeof options.wordBreak !== 'undefined') ? options.wordBreak : false,
            suffix = options.suffix || '...',
            moreLink = options.moreLink || '';
    
        var arr = html.replace(/</g, "\n<")
            .replace(/>/g, ">\n")
            .replace(/\n\n/g, "\n")
            .replace(/^\n/g, "")
            .replace(/\n$/g, "")
            .split("\n");
    
        var sum = 0,
            row, cut, add,
            tagMatch,
            tagName,
            tagStack = [],
            more = false;
    
        for (var i = 0; i < arr.length; i++) {
    
            row = arr[i];
            // count multiple spaces as one character
            rowCut = row.replace(/[ ]+/g, ' ');
    
            if (!row.length) {
                continue;
            }
    
            if (row[0] !== "<") {
    
                if (sum >= limit) {
                    row = "";
                } else if ((sum + rowCut.length) >= limit) {
    
                    cut = limit - sum;
    
                    if (row[cut - 1] === ' ') {
                        while(cut){
                            cut -= 1;
                            if(row[cut - 1] !== ' '){
                                break;
                            }
                        }
                    } else {
    
                        add = row.substring(cut).split('').indexOf(' ');
    
                        // break on halh of word
                        if(!wordBreak) {
                            if (add !== -1) {
                                cut += add;
                            } else {
                                cut = row.length;
                            }
                        }
                    }
    
                    row = row.substring(0, cut) + suffix;
    
                    if (moreLink) {
                        row += '<a href="' + moreLink + '" style="display:inline">»</a>';
                    }
    
                    sum = limit;
                    more = true;
                } else {
                    sum += rowCut.length;
                }
            } else if (!preserveTags) {
                row = '';
            } else if (sum >= limit) {
    
                tagMatch = row.match(/[a-zA-Z]+/);
                tagName = tagMatch ? tagMatch[0] : '';
    
                if (tagName) {
                    if (row.substring(0, 2) !== '</') {
    
                        tagStack.push(tagName);
                        row = '';
                    } else {
    
                        while (tagStack[tagStack.length - 1] !== tagName && tagStack.length) {
                            tagStack.pop();
                        }
    
                        if (tagStack.length) {
                            row = '';
                        }
    
                        tagStack.pop();
                    }
                } else {
                    row = '';
                }
            }
    
            arr[i] = row;
        }
    
        return {
            html: arr.join("\n").replace(/\n/g, ""),
            more: more
        };
    }
    
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = trimHtml;
    }
    


    usage

    var html = '<div><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p><p>Ut
    enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
    ex ea commodo consequat. </p><p>Duis aute irure dolor in reprehenderit in
    voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p><p>Excepteur
    sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
    anim id est laborum.</p></div>';
    var trim = trimHtml(html, { limit: 200 });
    
    
    // **returns object**
    
    
    {
       html: '<div><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
       sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p><p>Ut
       enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut...
       </p></div>',
       more: true // indicates if limit is reached
    }
    

    WORKING EXAMPLE

    0 讨论(0)
提交回复
热议问题