0

I'm trying to write a chrome extension that(for now) changes the background color of elements that have a certain 'class name'. This code(content script) doesn't work:

let divs = document.getElementsByClassName('arbitrary-class-name');

for (let el of divs) {
    el.style['background-color'] = 'FFF298';
}

I got "Uncaught TypeError: divs is not iterable" when i tried to execute. I also tried to inspect the source code and i noticed that all the elements that i wanted to get, are dynamically created during loading, maybe my code is trying to access elements that don't exist yet?

edit: this is the page i'm trying to work with, for instance i want to change the background color of all 'partecipante-info' divs.

edit2: This code always runs after my script:

XHR finished loading: POST "https://some-link".
send @ jquery-1.12.4.js:10254
ajax @ jquery-1.12.4.js:9738
(anonymous) @ genera_tabellone_v2.js:15
fire @ jquery-1.12.4.js:3232
fireWith @ jquery-1.12.4.js:3362
ready @ jquery-1.12.4.js:3582
completed @ jquery-1.12.4.js:3617

edoardo
  • 35
  • 7
  • The `divs` variable should be iterable as `getElementsByClassName` returns a `HTMLCollection` which has the iterator protocol. So your `divs` value is something other than a `HTMLCollection`. – Emiel Zuurbier Oct 26 '20 at 20:47
  • when you use for of is itterable you can work htmlCollection. so you don't find element. – Robert Oct 26 '20 at 20:48

1 Answers1

0

Introduction

If the elements are generated dynamically, you need to run your code after the elements are generated.

You could use a few approaches, but I have 2 suggestions:

  1. You could try running the code once, when the page is loaded. Have a look @ the following links. If you want to detect the chrome tab events you could use this: Chrome Extension: Make it run every page load . Otherwise you could also try listening for a body onload but I don't know if that would work.

  2. Another option would be to use SetInterval and search for the specific elements at specific times. Put this inside the chrome.tabs.onUpdated and check every 1 second.. when you have found the elements with the specific class disable the setInterval.

Possible Example

   chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
      if (changeInfo.status == 'complete') {
    
            // do your things
        
        let divs = document.getElementsByClassName('arbitrary-class-name');

        //Check if iterable         
        if(divs == null || typeof divs[Symbol.iterator] !== 'function'){
             return;
        }

        if(di)
        for (elt of divs) {
            elt.style['background-color'] = 'FFF298';
        }
    
    
      }
    })

References

Menelaos
  • 23,508
  • 18
  • 90
  • 155
  • It seems the problem come from the fact that jquery code is executed after my content.js script, so my code is overwritten. – edoardo Oct 26 '20 at 22:50