0

If there are many <div>s in some web page like this:

<div tbinfo="ouid=1234567890&rouid=987654321"></div>
<div tbinfo="ouid=1234567891&rouid=987654321"></div>
<div tbinfo="ouid=1234567892&rouid=987654321"></div>
...

I have this content scripts, trying to remove some division(s) from them, if either ouid or rouid matches some key:

var i;
for (i = 0; i < arrID.length; i++) {
    chrome.tabs.query(
        {active: true}, function(tabs) {
            var tab = tabs[0];

            let code = `document.querySelectorAll('div[tbinfo]')`;

            chrome.tabs.executeScript(tab.id, {code}, function (result) {
                const key = arrID[i];
                result.forEach(div => {
                    const tbinfoArr = div.getAttribute('tbinfo');
                    if (tbinfoArr.includes(key)) {
                        div.remove();
                    }
                });
            });
        }
    );
}

But chrome says Error handling response: TypeError: div.getAttribute is not a function

What's wrong here?


Suggested by @wOxxOm, I modified my code as below:

for (i = 0; i < arrID.length; i++) {
    alert(arrID[0] + ' ' + (typeof arrID[0])); // Alert No.1 // result: 123456789 string
    chrome.tabs.query(
        {active: true}, function(tabs) {
            var tab = tabs[0];

            const params = { ID: arrID[i] };
          alert(arrID[i] + ' ' + JSON.stringify(params)); // Alert No.2 // result = undefined {}

         alert(`(${ removeContent })(${ JSON.stringify(params) })`); // Alert No.4
            chrome.tabs.executeScript({
                code: `(${ removeContent })(${ JSON.stringify(params) })`
            }, ([result] = []) => {
                //
            });
        }
    );
}

function removeContent(ID) {
    var allElement = document.querySelectorAll('div[tbinfo]');
    alert(JSON.stringify(ID)); // Alert No.3
    var key = ID.ID;
    allElement.forEach(div => {
        const tbinfoArr = div.getAttribute('tbinfo');
        if (tbinfoArr.includes(key)) {
            div.remove();
        }
    });
    return {
        success: true,
    };
}

alert(JSON.stringify(ID)); shows that ID parameter is empty (result: {}).

So I tested ID's value and discovered that // Alert No.1 worked well, but // Alert No.2 was empty.

So it seems like variable outside of chrome.tabs.query( cannot be referenced inside??


The value of (${ removeContent })(${ JSON.stringify(params) }) is

(function removeContent(ID) {
    var allElement = document.querySelectorAll('div[tbinfo]');
    var key = ID.ID;
    allElement.forEach(div => {
        const tbinfoArr = div.getAttribute('tbinfo');
        if (tbinfoArr.includes(key)) {
            div.remove();
        }   
    });
    return {
        success: true,
    };
}) ({})

This value comes from // Alert No.4.

  • well, `div` is definitely not a jQuery object - because you don't use jQuery - but it does seem odd that getAttribute isn't a function – Jaromanda X Mar 16 '20 at 00:00
  • You can't transfer elements via executeScript. Only simple types such as strings/numbers and arrays or objects of such simple types can be transferred. Do the processing inside your `code` e.g. [How to access the webpage DOM rather than the extension page DOM?](https://stackoverflow.com/a/4532567) – wOxxOm Mar 16 '20 at 04:21
  • @wOxxOm If I do the processing inside my code, when I need actual `key` value generated from outside (e.g. `var key = arrayFromOutside[0];`), is it going to have scope problems? – Taihouuuuuuuuuuu Mar 16 '20 at 10:41
  • @wOxxOm I modified my code as suggested in that post and updated my question. – Taihouuuuuuuuuuu Mar 16 '20 at 12:41
  • @wOxxOm That is just a number in string type. I tried `alert(arrID[0] + ' ' + (typeof arrID[0]));`, and the result is : `5510540272 string` – Taihouuuuuuuuuuu Mar 16 '20 at 15:30
  • @wOxxOm Question updated. – Taihouuuuuuuuuuu Mar 16 '20 at 17:30
  • @wOxxOm I think the problem is somehow `arrID[i]`'s value hasn't been passed into `chrome.tabs.query{}`, because in `// Alert No.2`, arrID[i] is `undefined`, even before the callback function is triggered. (but its value does exist right before `chrome.tabs.query{}`... so confusing – Taihouuuuuuuuuuu Mar 16 '20 at 17:57
  • Sounds like [Asynchronous Process inside a javascript for loop](https://stackoverflow.com/a/11488129) – wOxxOm Mar 16 '20 at 18:05
  • @wOxxOm Thank you so much for that link! It worked. – Taihouuuuuuuuuuu Mar 16 '20 at 18:40

1 Answers1

0

As discussed in this post, asynchronous process inside for loop will cause problems.

Replace for loop by forEach solved the problem.