skip to Main Content

I need to change the font of all digits in the page.

I thought about using insertBefore() and so on – but then I realized it can’t be used with strings.

What I currently have:

  1. An array with all the text in the page.

  2. An array with all digits.

  3. An array with all digits replaced with the replace() function (A failed attempt).

I also tried to create a for loop that would loop over all words in the array and assign them an element created with a variable – but apparently they can’t be accessed.

How could I wrap all items of the 'string' array with a span or any other tag?

NOTE: I’d rather not use innerHTML.

Thank you very much!

let allText = document.querySelector('body p').textContent;
console.log(allText);

let digits = allText.match(/d/gi);
console.log(digits);

let rep = allText.replace(/d/gi, "AA");
console.log(rep);
document.body.textContent = rep;
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        body {
            text-align: center;

            font-size: 40px;
        }
    </style>
</head>
<body>
    <p>
        sdfjsdf
        (1): sdfdsdfs --
        (1): sdfdsdfs --
        (2) sdfsdf --
        (3): sdfsdfs --
        sdfdsfsdf --
    </p>

    <script src="a.js"></script>
</body>
</html>

2

Answers


  1. As long as there are no numbers inside tags inside the content

    I changed to pre to keep the list

    NOTE: The use of innerHTML CAN have some XSS issues. If the content of the P tag has not been sanitized, you do run a risk. So here is a version that is XSS safe. I just read in your comment that you did not want innerHTML anyway

    let allText = document.querySelector('body p').textContent;
    console.log(allText);
    const outputElement = document.getElementById('output');
    outputElement.textContent= ''; // empty the output
    
    allText.split('n').forEach(line => {
      // Create a container for the line
      const lineElement = document.createElement('div');
      // Split the line into parts by numbers, capturing the numbers to keep them in the result
      const parts = line.split(/(d+)/);
      console.log(parts)
      parts.forEach(part => { 
        if (/d+/.test(part)) {
          // wrap a number in a span
          const span = document.createElement('span');
          span.className = 'number';
          span.textContent = part;
          lineElement.appendChild(span);
        } else {
          lineElement.appendChild(document.createTextNode(part));
        }
      });
      outputElement.appendChild(lineElement);
    });
    .number {
      color: red;
    }
    
    /* stop console.log from hiding output */
    .as-console-wrapper { height:40px !important;}
    <p>
            sdfjsdf
            (1): sdfdsdfs --
            (1): sdfdsdfs --
            (2) sdfsdf --
            (3): sdfsdfs --
            sdfdsfsdf --
        </p>
    
    <pre id="output"></pre>

    If you are not bothered, then here is a simpler version

    let allText = document.querySelector('body p').textContent;
    console.log(allText);
    
    document.getElementById('output').innerHTML = allText
      .replace(/d+/g, match => `<span class="number">${match}</span>`)
    .number {
      color: red;
    }
    
    
    .as-console-wrapper { height:40px !important;}
    <p>
            sdfjsdf
            (1): sdfdsdfs --
            (1): sdfdsdfs --
            (2) sdfsdf --
            (3): sdfsdfs --
            sdfdsfsdf --
        </p>
    
    <pre id="output"></pre>
    Login or Signup to reply.
  2. If the objective is to wrap each number sequence in the document, here’s one approach:

    // Find all the document's text nodes
    const treeWalker = document.createTreeWalker(
      document.body,
      NodeFilter.SHOW_TEXT,
    );
    
    // Collect the text nodes into an array
    const nodes = [];
    while (treeWalker.nextNode()) {
      nodes.push(treeWalker.currentNode);
    }
    
    // Go through each text node...
    for (const node of nodes) {
      const matches = [
        // Find each string of digits, adding them to an array...
        ...node.data.matchAll(/d+/g)
        //  ...so that we can reverse them (we do this so our indexes
        //    don't become stale after we wrap the first text node)
      ].reverse();
      for (const match of matches) {
        // Create a range to include the sequence of digits
        const range = document.createRange();
        range.setStart(node, match.index);
        range.setEnd(node, match.index + match[0].length);
        // Create our wrapping element
        const newParent = document.createElement('b');
        // Surround the digits with our wrapping element
        range.surroundContents(newParent);
      }
    }
    <p>This text has 123 some numbers 456 including <i>nested 789</i>.</p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search