-1

I have an array of markup-strings like e.g.

const array = [
  '<p class="item">text</p>',
  '<h1>hello</h1>',
];

I want to replace the text-content of each markup-string's first tag. I thought of using the replace method but since it's not always a <p> tag and sometimes a tag's markup features a class-attribute, I can't rely on just targeting the text between <p> and </p>. I tried to use jQuery's html method but it's not working.

How could one achieve the just described task?

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Filou
  • 25
  • 5

1 Answers1

0

Parsing any kind of markup should not be left to regex based approaches, due to the latter by design can not compete with a specialized parser.

Thus said, the OP might have a look into DOMParser and DOMParser.parseFromString (for parsing) as well as into HTMLElement.innerText (text replacement) and Element.outerHTML (serializing again).

function replaceContentOfFirstTagInMarkup(markup, content) {
  const targetNode = (new DOMParser)
    .parseFromString(markup ?? '', "text/html")
    ?.body
    ?.firstElementChild ?? null;

  if (targetNode !== null) {

    targetNode.innerText = content ?? '';
    markup = targetNode.outerHTML;
  }
  return markup;
}

const markupList = [
  '<p class="item">text</p>',
  '<h1>hello</h1>',
];
const contentReplacementList = [
  'the quick brown fox',
  'Hello world',
];

const newMarkupList = markupList
  .map((markup, idx) =>
    replaceContentOfFirstTagInMarkup(
      markup, contentReplacementList[idx]
    )
  );
console.log({
  markupList,
  contentReplacementList,
  newMarkupList,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

A possible jQuery based implementation could look like that.

const markupList = [
  '<p class="item">text</p>',
  '<h1>hello</h1>',
];
const contentReplacementList = [
  'the quick brown fox',
  'Hello world',
];

const newMarkupList = [];

$(markupList)
  .each((idx, markup) => newMarkupList
    .push(
      $(markup)
        .empty()
        .text(contentReplacementList[idx])
        [0]
        .outerHTML
    )
  );
console.log({
  markupList,
  contentReplacementList,
  newMarkupList,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37