Search code examples
reactjsmarkdown-it

seemore/hide post with markdown content


My reactjs web app display feed post content look like Facebook Workplace. ​My post data API:

post = { plainText: "some text", markdownText: "some **text**" }

I use lib mardown-it to convert markdown string to HTML. Post need seemore/hide content (like facebook workplace). I'm stuck when get collapse content.

Example:

Full content: "blah blah some (and very long text) **text** blah blah"

Full content HTML: <p>blah blah some (and very long text) <strong>text</strong>blah blah</p>

Collapse content (cut from markdownText): "blah blah some (and very long text) **tex"

I got wrong collapse content HTML: <p>blah blah some (and very long text) **tex</p>

My expect: <p>blah blah some (and very long text) <strong>tex</strong></p>

How can I get exactly collapse HTML like facebook workplace post. Thank for your help.


Solution

  • You can solve the problem with a recursive function which filter content.

    • Load HTML content to dom element
    • Create a new element and recursive function which filter content
    • Apply some filtering logic like max allowed text size
    • Clone text elements and append to a new element
    • Also you can add 'load more' button at the end instead of '...'

    Example:

    var fullElement = document.createElement('div');
    fullElement.innerHTML = '<p>blah blah some (and very long text) <strong>tex</strong> next text<strong>tex</strong></p>';
    var shortElement = document.createElement('div');
    var allowedSize = 40;
    var currentSize = 0;
    function applyNodes(element, parent){
      for (let item of element.childNodes) {
        if (item.nodeType === Node.ELEMENT_NODE) {
          var newParent = document.createElement(item.nodeName);
          parent.appendChild(newParent);
          applyNodes(item, newParent);
        } else {
          var diff = allowedSize - currentSize;
          var value = item.textContent;
          if (item.textContent.length >= diff) {
            value = value.substring(0, diff) + '...';
            parent.append(value);
            currentSize += value.length;
            return;
          } else {
            parent.append(value);
            currentSize += value.length;
          }
        }
      }
    }
    applyNodes(fullElement, shortElement);
    console.log(shortElement.innerHTML);
    

    Output:

    <p>blah blah some (and very long text) <strong>tex</strong> ...</p>