Search code examples
javascriptmutation-observers

Is there a way to add a script that runs before any elements are added to the DOM but that relies on the body element?


I am attempting to check every mutation on a page using MutationObserver.

Is there a simple way to fix the following so I don't have to include it in the body (i.e. include it in the <head>) as an inline script?

The issue comes with the fact that I need the bodyList variable to be able to start monitoring items added to the page.

Obviously I can't use the onLoad event or anything as by then the mutations have all occurred (unless there is a way of accessing them after the fact I am unaware of?).

Or is there a way to attach the mutation observer to the document itself rather than an element?

I am sure the answer is simple but I can't find any documentation that covers this.

<body>
<script>
//I want to move this inline script into the <head>
var bodyList = document.querySelector("body"),
            observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                   console.log("MUTATION", mutation)
                });
            });
    observer.observe(bodyList, {childList: true, subtree: true});
</script>
....all the HTML elements that I want to monitor

Solution

  • You can attach an observer to the HTML document itself, wait for the <body> to appear, then attach an observer to the body:

    // In the <head>:
    new MutationObserver((_, observer) => {
        const { body } = document;
        if (!body) return;
        // Remove this observer, since it's not needed anymore; body exists
        observer.disconnect();
        new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                console.log("MUTATION", mutation)
            });
        })
            .observe(body, { childList: true, subtree: true });
    })
        .observe(document.documentElement, { childList: true });