Nodejs ejs显示带有html标签的内容,再截取部分内容时导致下面的样式乱掉

Nodejs ejs显示带有html标签的内容,再截取部分内容时导致下面的样式乱掉

想在页面上展示文章的部分内容,用substring(0,200)截取,由于文章内容使用富文本编辑器编辑的,所以会带有html标签, 这样的话截取的时候就会把html标签页算进去,结果就会出现标签不完整现象,会把非文章内容的标签也包含进文章为结束的标签内,样式就会乱掉,这种情况改怎么解决。用的是<%- %>,<%=%>会把html标签页显示出来

3 回复

在使用 Node.js 和 EJS 渲染包含 HTML 标签的文章片段时,如果直接使用字符串截取方法(如 substring),可能会导致 HTML 标签不完整,从而破坏页面样式。为了正确处理这种情况,我们需要确保截取的字符串保持 HTML 的完整性。

解决方案

  1. 使用正则表达式匹配完整的 HTML 元素:我们可以编写一个函数来截取包含完整 HTML 元素的字符串片段,而不是简单地截取字符长度。

  2. 使用模板引擎特性:EJS 提供了安全和不安全的输出方式,使用 <%- %> 输出不转义的内容,而 <%= %> 输出转义后的 HTML 内容。这里我们使用 <%- %> 来防止 HTML 被转义。

示例代码

文章数据

假设你的文章数据如下:

const article = {
    content: "<p>这是一篇文章的开头部分。<strong>这里有一些加粗的文字。</strong> 这是文章的中间部分。<a href='#'>链接</a> 这是文章的结尾部分。</p>"
};

截取并渲染文章片段

<% 
function truncateHtml(html, length) {
    let truncated = html.slice(0, length);
    const lastSpace = truncated.lastIndexOf(' ');
    if (lastSpace !== -1) {
        truncated = truncated.slice(0, lastSpace);
    }
    return truncated + '...';
}
%>

<div class="article-content">
    <%- truncateHtml(article.content, 200) %>
</div>

解释

  1. truncateHtml 函数

    • 接收两个参数:HTML 字符串和需要截取的长度。
    • 使用 slice 方法截取前 length 个字符。
    • 检查最后的空格位置,并在最后一个空格处截断字符串以避免截断单词。
    • 返回截取后的字符串,并添加省略号。
  2. EJS 模板

    • 使用 <%- %> 来输出不转义的 HTML 内容。
    • 调用 truncateHtml 函数来截取文章内容并输出到页面。

这种方法可以确保截取的内容不仅长度合适,而且 HTML 标签也是完整的,不会导致样式混乱。


生成独立的summary, 或者 过滤文章的标签(正则)再 substr

在这个问题中,你需要在截取文章部分内容时确保HTML标签是完整的,从而避免样式混乱。你可以通过以下几种方法来解决这个问题:

方法1: 使用第三方库解析HTML内容

你可以使用如htmlparser2这样的库来解析HTML内容,并确保在截取内容时不会破坏标签结构。

const htmlparser = require('htmlparser2');

function getPartialHtml(html, maxLength) {
    let parser = new htmlparser.WritableStream({
        write(chunk) {
            this._buffer += chunk;
            while (true) {
                let index = this._buffer.indexOf('<');
                if (index === -1 || this._buffer.length - index > maxLength) {
                    break;
                }
                let endIndex = this._buffer.indexOf('>', index);
                if (endIndex === -1) {
                    break;
                }
                let tag = this._buffer.substring(index, endIndex + 1);
                this.emit('data', tag);
                this._buffer = this._buffer.substring(endIndex + 1);
            }
            let text = this._buffer.slice(0, maxLength);
            this.emit('data', text);
            this._buffer = this._buffer.slice(maxLength);
        }
    });

    parser.write(html);
    return parser._buffer;
}

// 在EJS模板中使用
<%- getPartialHtml(article.content, 200) %>

方法2: 手动处理HTML标签

如果你不想引入额外的依赖,可以手动处理HTML标签,确保它们不会被意外截断。

function getPartialHtml(html, maxLength) {
    let buffer = '';
    let openTags = [];
    for (let i = 0; i < html.length && buffer.length < maxLength; i++) {
        let char = html[i];
        if (char === '<') {
            let j = html.indexOf('>', i);
            if (j !== -1) {
                let tag = html.substring(i, j + 1);
                if (tag.startsWith('</')) {
                    openTags.pop();
                } else {
                    openTags.push(tag);
                }
                buffer += tag;
                i = j;
            }
        } else {
            buffer += char;
        }
    }
    return buffer + openTags.join('');
}

// 在EJS模板中使用
<%- getPartialHtml(article.content, 200) %>

以上两种方法都能有效解决截取带HTML标签内容时出现的样式问题。选择哪种方法取决于你的具体需求和项目复杂度。

回到顶部