R. Dureya
R. Dureya

Reputation: 53

How to create a Chrome Extension to Hide or Remove a Page Element using JavaScript?

I am trying to create a Chrome Extension to manipulate the HTML on a page. The extension should remove or hide some elements from a page when activated.

I created a simple manifest.json file:

{
  "manifest_version": 2,

  "name": "hide-msgs-ext",
  "version": "0.0.1",
  "description": "Hide msgs extension",

  "content_scripts": [{
    "js": ["content.js"],
    "matches": ["https://website.example.com/*"],
    "run_at":  "document_idle"
  }]

}

and a script content.js, which should remove/hide all my target elements:

var elements = document.querySelectorAll('div.card');
for (var i = 0, l = elements.length; i < l; i++) {
  subElement = elements[i].querySelector(':scope div.card-body');
  if (subElement.firstChild.tagName != 'A') {
    elements[i].style.display = "none";
  }
}

If I execute the above script in the chrome console I am able to hide all the elements I want and no errors are triggered. However I could not figure it out how to make it work in the extension.

Could someone point me in the right direction? Thanks you in advance!

Upvotes: 5

Views: 2733

Answers (1)

Jason Goemaat
Jason Goemaat

Reputation: 29214

It sounds like the content might be created by javascript after the page loads so you need to wait for it to appear. You can wrap your code in a function and execute it after a timeout:

function hideCards() {
  var elements = document.querySelectorAll('div.card');
  for (var i = 0, l = elements.length; i < l; i++) {
    subElement = elements[i].querySelector(':scope div.card-body');
    if (subElement.firstChild.tagName != 'A') {
      elements[i].style.display = "none";
    }
  }
}

// execute after a second to give the page time to create the
// elements you want to remove
setTimeout(hideCards, 1000);

If you want it to work throughout the life of the page and be very quick, you could try using MutationObserver. This lets you listen for DOM changes. Here's a sample of how to use that. The 'Add Item' button adds a new item, every other one has the 'remove-me' class. The MutationObserver executes a function that automatically removes any LI nodes added with that class so they don't appear:

const observer = new MutationObserver(function(mutations) {
  let added = [];
  for (let i = 0; i < mutations.length; i++) {
    let m = mutations[i];
    for (let j = 0; j < m.addedNodes.length; j++) {
      let n = m.addedNodes[j];
      if (n.tagName === 'LI' && n.classList.contains('remove-me')) {
        added.push(n);
      }
    }
  }
  added.forEach(element => element.remove())
});

const config = { subtree: true, childList: true };
observer.observe(document.body, config);
 
let index = 0;
document.getElementById('btnAddItem')
.addEventListener('click', (event) => {
  let li = document.createElement('li');
  if (index & 1 == 1)  li.classList.add('remove-me');
  li.innerText = `Item ${index++}`;
  document.getElementById('myList').appendChild(li);
});
<ol id="myList">
  <li>First Item</li>
</ol>

<button id="btnAddItem">Add Item</button>

Upvotes: 2

Related Questions