vmonteco
vmonteco

Reputation: 15403

Is it possible to run two MutationObservers at the same time?

I'm trying to make a script with Greasemonkey for the Facebook's Timeline log page.

I need to catch two kind of events :

1)The URL change (Since the changes are made with AJAX on Facebook and therefore the page isn't fully reloaded, and neither the script).

2)The appearance of some elements.

I tried to make two MutationObservers, one to catch URL changes, and the other to catche the elements appearance. But it seems to trigger only one (the url_mutation_observer).

Here is some of my code :

function handling_url_change(mutations){
    mutations.forEach(function (mutation){
        if (check_timeline()){
            if (!buttons_added){
                var element = $(document).find(button_location);
                if (element && element.length > 0){
                    add_buttons();
                }
            }
        }else if (set){
            reset();
        }
    });
}

function handle_deletion(mutations){
    mutations.forEach(function (mutation){
        if (mutation.addedNodes){
            for (var i = 0; i < mutation.addedNodes.length; i++){
                if (isheader(mutation.addedNodes[i])){
                    mutation.addedNodes[i].remove()
                }else if (isactivity(mutation.addedNodes[i])){
                    delete_activity(mutation.addedNodes[i]);
                }
                return true;
            }
        }
    });
    return true;
}

/*
** Mutation observers :
*/

var url_mutation_observer = new MutationObserver(handling_url_change);

var delete_mutation_observer = new MutationObserver(handle_deletion);

I have some questions :

1) Isn't each MutationObserver catching every mutation?

2) Is the addition of a button (like my script does) counted as a mutation?

3) If I add an element with a callback function triggered by the addition of such element. Isn't there a risk of recursion and infinite loop?

4) Is that possible to catch only the URL change with a MutationObserver, and to catch the appearance of only some kinds of elements with the other one? (To be sure that each one catches only what he needs to catch, I didn't know how to do and I checked the url with a function inspecting the page, and not with a function checking if the mutation is a "UrlChangeMutation" or something like that).

5) What could I do?

NB: If you want too, here is the full script with console.log() calls for debugging. http://dpaste.com/3NWV08J

NB2: If you also want this script without the console.log() calls : http://dpaste.com/3AH8YF5

Upvotes: 0

Views: 2681

Answers (2)

vmonteco
vmonteco

Reputation: 15403

I had an error : observer.observer() isn't a function. observer.observe() is : http://dpaste.com/3AH8YF5#line-254

Upvotes: 0

Siguza
Siguza

Reputation: 23850

First off, note that your for loop is broken, because it contains an unconditional return true.

1) Isn't each MutationObserver catching every mutation?

Yes, because you're observing document.

2) Is the addition of a button (like my script does) counted as a mutation?

Of course.

3) If I add an element with a callback function triggered by the addition of such element. Isn't there a risk of recursion and infinite loop?

Absolutely.
(It will be a non-blocking loop though, meaning the page might not freeze.)

4) Is that possible to catch only the URL change with a MutationObserver [...]?

No, that's not what MutationObservers do. From MDN:

MutationObserver provides developers a way to react to changes in a DOM.

Note that "UrlChangeMutation or something like that" does not exist.

4) [...] and to catch the appearance of only some kinds of elements with the other one?

You cannot specify a filter, but you can check whether the affected elements meet your criteria in your callback function.
Hell, you have access to all methods and attributes of every node, what more could you need?

5) What could I do?

My suggestion? Google more.
For example, the first result for "javascript on url change" is:

How to detect url change

And I suggest you read up on the DOM, because it seems that you are simply unaware of many things that exist there.

Upvotes: 3

Related Questions