skip to Main Content

I have a dynamically created div with styled characters such as:
<div>Hello <b>J</b>oe</div>
and I am trying to figure out which characters are styled (in this case the J).

I have already tried window.getComputedStyle() but I was unsuccessful in getting the style character by character.

Bigger example:

<div id="testing">H<b>i</b> I <b>a</b>m b<b>o</b>b</div>

Expected output:
getDivStyle("testing") =>

H: false
i: true

I: false

a: true
m: false

B: false
o: true
b: false

Thank you for your help!

3

Answers


  1. If it is only bolded elements, you could do this:

    HTML:

    <div id="my-div">Hello <b>J</b>oe</div>
    

    JavaScript:

    console.log(document.getElementById("my-div").querySelectorAll("b"));
    

    Essentially, what you are doing is you are printing all the <b> elements in the div.

    However, the above applies to only bolded elements. If you would like to do it with more than just bolded elements, you can do this, but you need to know ALL the element tags. Like so:

    HTML:

    <div id="my-div"><i>Hello</i> <b>J</b>oe</div>
    

    JavaScript:

    console.log(document.getElementById("my-div").querySelectorAll("b"), document.getElementById("my-div").querySelectorAll("i"));
    
    Login or Signup to reply.
  2. Read the child nodes and you can look at the text, type, and node value. You can easily split it on characters to get the output.

    const nodes = document.querySelector("#testing").childNodes;
    nodes.forEach(node => {
      console.log(node.textContent, node.nodeType === Node.ELEMENT_NODE, node.nodeName);
    });
    <div id="testing">H<b>i</b> I <b>a</b>m b<b>o</b>b</div>

    so now to get the output

    const nodes = document.querySelector("#testing").childNodes;
    const result = Array.from(nodes).flatMap(node => {
      const isElem = node.nodeType === Node.ELEMENT_NODE;  
      return Array.from(node.textContent).map(char => char === ' ' ? '' : `${char}: ${isElem}`);
    });
    
    console.log(result.join("n"));
    <div id="testing">H<b>i</b> I <b>a</b>m b<b>o</b>b</div>
    Login or Signup to reply.
  3. You can iterate the element’s child nodes (recursively) and accumulate a mapping of the characters to their parent elements. After collecting that list, you can map over it, deciding which types of elements are considered "styled", and convert those to boolean values.

    Here’s a complete example that will work with the input you showed. It will also work with nested elements and it will allow you to modify which types of elements are the "styled" ones:

    Code in TypeScript Playground

    /** @returns an array of [character, parent element] */
    function createTextMapping(element, memo = []) {
      for (const node of element.childNodes) {
        switch (node.nodeType) {
          case Node.TEXT_NODE: {
            for (const str of node.data) {
              memo.push([str, element]);
            }
            break;
          }
          case Node.ELEMENT_NODE: {
            createTextMapping(node, memo);
            break;
          }
          default: throw new Error("Unexpected node type");
        }
      }
      return memo;
    }
    
    // Define which elemnet tag names are considered "styled":
    const styledElementTagNames = new Set([
      "B",
      "EM",
      "I",
      "STRONG",
      // etc.
    ]);
    
    const targetElement = document.getElementById("testing");
    
    const mapping = createTextMapping(targetElement);
    
    const results = mapping
      .filter(([str]) => str.trim().length > 0) // Remove whitespace
      .map(([str, elm]) => [str, styledElementTagNames.has(elm.tagName)]); // Validate parent elements
    
    for (const [str, valid] of results) {
      console.log(`${str}:`, valid);
    }
    body { font-family: sans-serif; }
    <div id="testing">H<b>i</b> I <b>a</b>m b<b>o</b>b</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search