Search code examples
javascripthtmlhtml-parsingdomparser

Iterate through HTML elements add a class name if it contains inline background-color


I have a user generated rich text content that needs to be modify with some additional static class names. I tried below JS code.

First I get the content and using DOMParser. Then iterate all elements, If any elements contains inline background-color, I need to add some random class name to that specific element and remaining elements should be same. When I try this below code it didn't execute the expected result. And also parent and child nodes rendering multiple times. How do I add class names if element contains background-color and return back the remaining elements with class name modified elements?

const content = `<div>
   <div style="font-size :  13px; font-family :  Arial,  Helvetica,  sans-serif; ">
      <div>
         <span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; "> please check the below concern and advice.<br /><br />Cx concern:&nbsp;</span></span></span><span style="font-size :  14px; font-family :  LatoRegular,  sans-serif; white-space :  pre-wrap; "><span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; ">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum</span></span></span></span><span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; "><br /></span></span></span>
      </div>
      <div><br /></div>
      <div><img style="padding :  0px; max-width :  100%; box-sizing :  border-box; " src="image.jpg" /><br /></div>
      <div><br /></div>
   </div>
   <br />
</div>`;

/*export*/ function modifyContent(content) {
  const doc = new DOMParser().parseFromString(content, "text/html");
  let element = doc.body.getElementsByTagName("*");
  let resultArray = [];
  let result = '';

  for (let i = 0; i < element.length; i++) {
    if (element[i].style.backgroundColor) {
        result += element[i].classList.add('someRandomClassName');
    } else {
        result += element[i];
    }
  }
  resultArray.push(result);
  console.log('output', resultArray);
  // return resultArray;
}

modifyContent(content);


Solution

  • Don't try to turn the result into a string until the very end, after adding all the classes - and to do that, take the constructed document's body's .innerHTML.

    function modifyContent(content) {
      const doc = new DOMParser().parseFromString(content, "text/html");
      // select only elements with a style attribute:
      for (const element of doc.querySelectorAll('[style]')) {
        if (element.style.backgroundColor) {
          element.classList.add('someRandomClassName');
        }
      }
      return doc.body.innerHTML;
    }
    
    const input = `<div>
      <div style="font-size :  13px; font-family :  Arial,  Helvetica,  sans-serif; ">
        <div>
          <span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; "> please check the below concern and advice.<br /><br />Cx concern:&nbsp;</span></span>
          </span><span style="font-size :  14px; font-family :  LatoRegular,  sans-serif; white-space :  pre-wrap; "><span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; ">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum</span></span>
          </span>
          </span><span class="x_965909101highlight" style="background-color :  rgb(255, 255, 255); "><span class="x_965909101font" style="font-family :  tahoma,  arial,  helvetica,  sans-serif,  sans-serif; "><span class="x_965909101size" style="font-size :  13px; "><br /></span></span>
          </span>
        </div>
        <div><br /></div>
        <div><img style="padding :  0px; max-width :  100%; box-sizing :  border-box; " src="image.jpg" /><br /></div>
        <div><br /></div>
      </div>
      <br />
    </div>`;
    console.log(modifyContent(input));