-1

I apologise for asking multiple questions all at once.

  1. I am trying to manipulate the content of a page using a chrome extension using this code:
let container = document.querySelector('p');
let newtext = container.innerHTML.split('').map(
    m => Math.random() > .49 ? <strong>${m}</strong> : m
);

container.innerHTML = newtext.join('')

The first problem I encounter is that the code only manipulates the first p of the page. I have tried using querySelectorAll(), but it does not work. The second is the code does not work on all the pages I load. Here is the code for my manifest.json file:

    {
        "manifest_version": 3,
        "version": "1.0",
        "name": "name",
        "description": "description",
        "action": {
            "default_title": "title",
            "default_popup": "popup.html",
            "default_icon": "icon.png"
        },
        "content_scripts": [
            {
                "js": ["content.js"],
                "matches": ["<all_urls>"],
                "run_at": "document_start"
            }
        ]

  }
  1. I am experiencing a new problem with my code (which I think might be a page-specific issue). Whenever I reload the page it displays the HTML tags that exist on the page, like this:
    strong>Question</strong>&nbsp; <span>How does the efficacy of cefepime/enmetazobactam compare with piperacillin/tazobactam for the treatment of complicated urinary tract infection (UTI) or acute pyelonephritis?</span>.

Any advice would be appreciated.

WOUNDEDStevenJones
  • 5,150
  • 6
  • 41
  • 53

1 Answers1

0

After doing document.querySelectorAll('p') you'll need to iterate over that NodeList (example at https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#accessing_the_matches).

And <strong>${m}</strong> needs backticks around it to indicate a template literal (How to interpolate variables in strings in JavaScript, without concatenation?) or you could concatenate the string like '<strong>' + m + '</strong>'.

Also, to handle nested HTML elements you should get the .innerText of the container, not .innerHtml to avoid breaking existing HTML.

let containers = document.querySelectorAll('p');

containers.forEach((container) => {
  // .innerText will ensure only text content gets potentially bolded
  // if you change this to .innerHTML it will break nested HTML elements.
  let newtext = container.innerText.split('').map(
    m => Math.random() > .49 ? `<strong>${m}</strong>` : m
  );
  
  container.innerHTML = newtext.join('')
});
<p>testing some text and random bolding</p>
<p>another test with some text</p>
<p>a third paragraph tag to test with</p>
<p>and one more for good measure</p>

<p><span>testing</span> some text <a>and nested tags</a></p>
WOUNDEDStevenJones
  • 5,150
  • 6
  • 41
  • 53
  • The solution above works perfectly. However, it causes me to experience the problem described at the second point. – Luthando Mkhwanazi Oct 10 '22 at 17:46
  • I'm not sure what #2 means. Could you either include a screenshot or explain in more detail what the problem is? Or better yet, add a minimal, reproducible example. It doesn't seem like and issue with your JS, but without more details I can't confirm. – WOUNDEDStevenJones Oct 10 '22 at 18:33
  • So what happens is on a page the paragraph will be displayed like: **Question? How does the efficacy of cefepime/enmetazobactam compare with piperacillin for the treatment of complicated urinary tract infections or acute pyelonephritis?** However, when I inject the JS it appears with HTML `tags`: **`strong>`Question` `How does the efficacy of cefepime/enmetazobactam compare with piperacillin for the treatment of complicated urinary tract infection or acute pyelonephritis?``.** Including `a` tags – Luthando Mkhwanazi Oct 11 '22 at 17:34
  • If its not clear still let me know. – Luthando Mkhwanazi Oct 11 '22 at 17:36
  • It's not clear what would be causing that without a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) to see it myself. It sounds like it's possibly an issue with using `.innerText` instead of `.innerHTML`. – WOUNDEDStevenJones Oct 12 '22 at 15:53
  • @WOUNDEDSteveJones that is quite not the problem. I have the images for issue no.2. [Before I run JS](https://imgur.com/DY7SlIO). [After I run JS](https://imgur.com/qI4qh2a) – Luthando Mkhwanazi Oct 13 '22 at 23:56
  • it's because in your screenshots, there are nested HTML elements inside of the selected elements (e.g. `

    `) but the example you provided only included `

    text

    `, which is why it appeared to work as expected on SO.com, but broke in your real test. This is the benefit of a [minimal, reproducible example](https://stackoverflow.com/help/how-to-ask) to narrow down the scope of where things are going wrong. This has been updated in my answer to account for nested elements (specifically, only editing a container's `.innerText`, not `.innerHTML`).
    – WOUNDEDStevenJones Oct 14 '22 at 15:36