Question

I'm currently trying to change style elements for this Google-tasks gadget:

https://mail.google.com/tasks/ig

using a chrome content script.

In this example, I'm removing the toolbar at the bottom. Because Google is generating the HTML with javascript, and puts it in an iframe. I need to use this code:

document.getElementsByTagName('iframe')[0].contentWindow.document.getElementById(':1.ft').style.display = 'none'

When you run this code from the developer console, it hides the toolbar. But it doesn't work as content script.

I thought this is because the code is run before the page is ready. So I tried to use an event listener:

document.addEventListener("DOMContentLoaded", function () {
document.getElementsByTagName('iframe')[0].contentWindow.document.getElementById(':1.ft').style.display = 'none'
}, false);

but that didn't work either. Also tried the event listeners 'domready' and 'load'. But none of them worked.

How do I get that element?

Was it helpful?

Solution

In this case, you could just make sure that this style rule is applied to the appropriate iframe(s), and not worry about when it is loaded:

#:1.ft {display: none !important;}

(^_^)
But, this may not be possible for iframes with src="javascript: ....


In the more general case. If that node (or its containing iframe) is loaded by AJAX, it no-doubt appears long after 'domready' or even 'load'.
The tried-and-true solution is to poll for the element:

var waitForElementIntrvl = setInterval (checkForElement, 333);

function checkForElement () {
    var firstIframe     = document.querySelector ("iframe");
    if (firstIframe) {
        var targElement = firstIframe.contentWindow.document.getElementById (':1.ft');
        if (targElement) {
            targElement.style.display = 'none';
            clearInterval (waitForElementIntrvl);
        }
    }
}


However:

Google Chrome content-scripts still do not play nice with iframed DOM's. So, in order for that code to work, it must be injected into the target page. The final content-script code becomes:

function userscriptMain () {
    var waitForElementIntrvl = setInterval (checkForElement, 333);

    function checkForElement () {
        var firstIframe     = document.querySelector ("iframe");
        if (firstIframe) {
            var targElement = firstIframe.contentWindow.document.getElementById (':1.ft');
            if (targElement) {
                targElement.style.display = 'none';
                clearInterval (waitForElementIntrvl);
            }
        }
    }
}

addJS_Node (null, null, userscriptMain);

function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top