Intercept and modify DOM before page is displayed to user

流过昼夜 提交于 2019-11-27 09:30:20

My problem is: can I perform modification on DOM (so: the HTML document that is returned by server) before the page even starts displaying?

Yes, javascript execution starts before the page is rendered the first time. The DOM Parser does notify mutation observers, so you can immediately strip elements as soon as they are added by the parser.

You can register mutation observers even in content scripts loaded with contentScriptWhen: "start" so they should be notified of all elements being added to the tree before they are rendered since the observer notifications are performed in the micro task queue while rendering happens on the macro task queue.

but I wasn't even able to get it to work: when attached as a pageMod on start the code failed on: document.getElementById('appcontent').addEventListener('DOMContentLoaded', function(e)

Of course. You should not assume that any element in particular - not even the <body> tag - is already available that early during page load. You will have to wait for them to become available.

And the DOMContentLoaded event can simply be registered on the document object. I don't know why you would register it on some Element.

(or event prevent any kind of page display before all page was loaded).

You don't really want that because it would increase page load times and thus reduce responsiveness of the website.

/*
 * contentScriptWhen: "start"
 *
 * "start": Load content scripts immediately after the document
 * element is inserted into the DOM, but before the DOM content
 * itself has been loaded
 */

/*
 * use an empty HTMLElement both as a place_holder
 * and a way to prevent the DOM content from loading
 */
document.replaceChild(
        document.createElement("html"), document.children[0]);
var rqst = new XMLHttpRequest();
rqst.open("GET", document.URL);
rqst.responseType = 'document';
rqst.onload = function(){
    if(this.status == 200) {
        /* edit the document */
        this.response.children[0].children[1].querySelector(
                "#content-load + div + script").remove();

        /* replace the place_holder */
        document.replaceChild(
                document.adoptNode(
                    this.response.children[0]),
                document.children[0]);

        // use_the_new_world();
    }
};
rqst.send();

If you want to get into it before any script has executed there are document observers here: https://developer.mozilla.org/en-US/docs/Observer_Notifications#Documents such as content-document-global-created

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!