【问题标题】:How do you truncate html text in React?你如何在 React 中截断 html 文本?
【发布时间】:2021-04-14 01:23:18
【问题描述】:

我正在尝试将以下 html 截断为 5 个字符:

<b>Hello</b> how are you today?

我要找的结果是:

你好

但是,如何忽略截断中的 html 标签,使其不会导致以下结果?

<b>He

我使用的是 html 解析器,所以在使用后我无法截断字符串。这是我的代码,不用说,它不起作用!

import React from 'react';
import parse from 'html-react-parser';
import Typography from '@material-ui/core/Typography';


const Message= () => {
  const message= "<b>Hello</b> how are you today?"
  const messageParsed = parse(message);

  return (
          <Typography variant="body2">
            {messageParsed.substr(0, 5)}
          </Typography>
  );
};

export default Message;

正确的做法是什么?

非常感谢,

凯蒂

【问题讨论】:

    标签: reactjs html-parsing truncate


    【解决方案1】:

    一种选择是您可以像这样使用 lodash/truncate 中的 _truncate:

    import _truncate from "lodash/truncate";
    import ReactHtmlParser from "react-html-parser";
    
    function ParsedText() {
      var text = "<b>Hello</b> how are you today?";
    
    
      return (
        <div> 
          {ReactHtmlParser(_truncate(text, { length: 5 }))}
        </div>
      )
    

    【讨论】:

      【解决方案2】:

      您可以使用Ranges保留html结构

      要获取一定长度的html,请在下方调用htmlToLength(html, length)

      您也可以通过调用 htmlToNodeWithLength(html, length) 来获取 DocumentFragment。

      这个算法的核心是findRangeWithLength(range, length),它从末尾(递归地)收缩range,直到得到给定的length

      function htmlToLength(html, length) {
        const trimmedNode = htmlToNodeWithLength(html, length);
      
        const container = document.createElement("div");
        container.appendChild(trimmedNode);
        return container.innerHTML;
      }
      
      function htmlToNodeWithLength(html, length) {
        // Only for measurement. Never added to DOM.
        const container = document.createElement("div");
        container.innerHTML = html;
      
        const fullRange = document.createRange();
        fullRange.setStart(container, 0);
        fullRange.setEnd(container, 1);
      
        const range = findRangeWithLength(fullRange, length);
        return range.cloneContents();
      }
      
      function findRangeWithLength(range, length) {
        if (rangeLength(range) < length) return range;
      
        // Find the childNode with at least length content.
        for (const childNode of range.endContainer.childNodes) {
          range.setEnd(childNode, lastEndOffset(childNode));
          if (rangeLength(range) >= length) {
            return findRangeWithLength(range, length);
          }
        }
      
        // There are no child nodes long enough. It's a text node.
        const diff = length - rangeLength(range) + range.endOffset;
        range.setEnd(range.endContainer, diff);
        return range;
      }
      
      function lastEndOffset(node) {
        return node.childNodes.length || node.textContent.length;
      }
      
      function rangeLength(range) {
        return range.toString().length;
      }
      
      const html = "<p>No <span></span><b>Hello</b> <i>World</i></p>";
      const length = 7;
      const trimmedNode = htmlToNodeWithLength(html, length);
      
      document.querySelector(".raw-input").textContent = html;
      document.querySelector(".trimmed").appendChild(trimmedNode);
      document.querySelector(".length").textContent = length;
      document.querySelector(".input").innerHTML = html;
      document.querySelector(".raw-output").textContent = htmlToLength(html, length);
      <h2>Raw HTML input</h2>
      <div class="raw-input"></div>
      <h2>Rendered Input</h2>
      <div class="input"></div>
      <h2>Rendered output to length <span class="length">?</span></h2>
      <div class="trimmed"></div>
      <h2>Raw HTML output</h2>
      <div class="raw-output"></div>

      【讨论】:

        【解决方案3】:

        我的理解是你有一个HTML文本,需要进行以下操作

        1. 删除 HTML 标签
        2. 将第 1 步后的字符串截断为 5 个字符。

        在这种情况下,可以使用正则表达式来完成。

        import React from "react";
        import "./styles.css";
        
        export default function App() {
          const message = "<b>Hello</b> how are you today?";
          const messageString = message.replace(/<(.|\n)*?>/g, '');
        
          const subText = messageString.substring(0, 5);
        
          return <div>{subText}</div>;
        }
        

        检查here 以获取工作样本。

        查看this & this 链接了解更多关于如何在 JS 中从字符串中删除 HTML 标记的信息。

        关于包html-react-parser,这不会返回字符串,因此substring 方法将不起作用。它返回一个数组。在您的情况下,parse(&lt;b&gt;Hello&lt;/b&gt; how are you today?); 行将返回以下内容

        【讨论】:

        • 您好 - 感谢您的回复。对此,我真的非常感激。我刚刚查看了您的代码沙箱,看来胆量正在丢失。我想将 html 标签保留在结果中,但不将它们计入截断。因此,字符串长度为 5 的结果应该是页面上呈现的 HelloHello
        猜你喜欢
        • 1970-01-01
        • 2016-05-05
        • 2020-09-30
        • 1970-01-01
        • 2021-01-23
        • 1970-01-01
        • 1970-01-01
        • 2017-11-23
        • 1970-01-01
        相关资源
        最近更新 更多