简体   繁体   中英

InsertAdjacentHTML gets overridden by HTML on page

I'm creating a browser extension and I've made it open a modal when I click on text on any webpage.

I used insertAdjacentHTML and for some reason any time I click to open the modal it uses the styling of the webpage/website I'm on rather than the styling that I gave it in the CSS file.

How can I get my CSS to rather override so that I keep my styling?

Where I believe the problem is happening:

// On mouse click
allText[i].addEventListener('click', async () => {
  // Load in HTML file
  fetch(chrome.runtime.getURL(findFontModal))
    .then(r => r.text())
    .then(html => {
      allText[i].insertAdjacentHTML('beforeend', html);
    });
});

Full js code:

// Receiving message from popup.js
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.switchStatus === "on") {
      // Getting all text elements
      const allText = document.querySelectorAll('h1, h2, h3, h4, h5, p, li, td, caption, span, a');
      const colors = ['#ffadad', '#ffd6a5', '#fdffb6', '#caffbf', '#bdb2ff', '#9fdfff'];
      const findFontModal = 'findfont.html'

      // Loop through all text elements-
      // to be able to manipulate each individual one
      for (let i = 0; i < allText.length; i++) {
        // On hover
        allText[i].addEventListener('mouseover', async () => {
          allText[i].style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
          allText[i].style.cursor = "pointer";
        });

        allText[i].addEventListener('mouseout', async () => {
          allText[i].style.backgroundColor = null;
        });

        // On mouse click
        allText[i].addEventListener('click', async () => {
          // Load in HTML file
          fetch(chrome.runtime.getURL(findFontModal))
            .then(r => r.text())
            .then(html => {
              allText[i].insertAdjacentHTML('beforeend', html);
            });
        })
      }

      sendResponse({ status: "done" });
    }

    // When toggle switch is unchecked
    else if (request.switchStatus === "off") {
      const allText = document.querySelectorAll('h1, h2, h3, h4, h5, p, li, td, caption, span, a');
      for (let i = 0; i < allText.length; i++) {
        allText[i].style.backgroundColor = null;
      }

      sendResponse({ status: "done" });
    }
  }
);

Modal HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="content.css">
    <title>Find Font Modal</title>
</head>
<body>
    <div class="modal-div">
        <div class="titlebar">
            <i class="fas fa-times"></i>
        </div>

        <div class="main-content">
            <div class="names">
                <h1>Font Name</h1>
                <h5>Foundry Name</h5>
            </div>
            <div class="font-props">
                <div class="color-div">
                    <span class="dot"></span>
                    <h4>#000000</h4>
                </div>

                <div class="actual-props">
                    <div class="column-1">
                        <h4>Font Weight</h4>
                        <h3>Blank</h3>

                        <h4 class="second">Line Height</h4>
                        <h3>Blank</h3>
                    </div>

                    <div class="column-2">
                        <h4>Font Size</h4>
                        <h3>Blank</h3>
                    </div>
                </div>
            </div>

            <div class="buttons">
                <button class="tryfont-btn">Try out this font</button>
            </div>
        </div>
    </div>

    <script src="https://kit.fontawesome.com/7ad5f72cd3.js" crossorigin="anonymous"></script>
</body>
</html>

Code on Github: https://github.com/JojoDuke/fs-extension-core

I believe the reason for confusion in the original question stems from the difference in how browser extensions apply scripts and styles to the browser tab:

  • scripts are sandboxed and have their own content script context, isolated from the scripts of the web page currently loaded in the tab
  • stylesheets are applied to the page along with the styles of the domain: styles of extension can overlap, override styles of the page, and vice versa.

This means when dynamically creating and appending elements to the DOM using insertAdjacentHTML , the styles of the webpage will be applied to this new element as well.

To ensure extension styles - and only extension styles - are applied to an element, use shadow DOM , which will encapsulate the elements and isolate its style from the rest of the page. Also review options for styling the shadow DOM .

Here is a simplified example, which I have used in a browser extension previously, to demonstrate this concept:

// create a container for the shadow DOM
// (or alternatively use some existing element in the DOM)
const container = document.createElement('div');
document.body.appendChild(container);
const shadow = container.attachShadow({mode: 'closed'});

// this elements will go inside the shadow DOM
// and it will have its own isolated style
const panel = document.createElement('div');
panel.style.position = "fixed";
panel.style.top=0;
panel.style.left=0;
panel.style.zIndex=2147483647;
panel.style.background="red";
panel.style.color="white";
panel.style.height = "100px";
panel.style.width = "250px";
panel.innerText="hello shadow world!";
shadow.appendChild(panel);

Use classes and IDs that are unique to your extension.. all querySelectors you are working with, and the modal's HTML should have class names and IDs all with lets say a prefix of the name of your extension..

like class="modal-div" would be something like: class="_my_extension_modal-div" , and so on. This way you would not overlap with any website's classes/IDs.


Another hack is to add !important to your CSS, but this might not work, or might brake the actual website when viewing it with your extension enabled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM