Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect change in document title via Javascript [duplicate]

Is there any way to detect a change to document.title / head > title via Javascript? I want to detect this via a Google Chrome extension content script, so I can't really wire up code in the target page's JS where the actual title change is performed.

I've found WebKitMutationObserver which theoretically should be able to detect a change to head > title, but it doesn't work for all cases:

// set up an observer for the title element
var target = document.querySelector('title');
var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation);
    });
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);

// this jQuery statement fires the observer as expected ...
$('head > title').text('foo');

// ... but this doesn't:
document.querySelector('title').innerText = 'cheezburger';

// ... and neither does this:
document.title = 'lorem ipsum';

Any ideas?

like image 566
joelpt Avatar asked Jul 27 '12 18:07

joelpt


2 Answers

I have found a fully working solution which is only a small modification to the example I posted in the original post.

// set up an observer for the title element
var target = document.querySelector('head > title');
var observer = new window.WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log('new title:', mutation.target.textContent);
    });
});
observer.observe(target, { subtree: true, characterData: true, childList: true });

// all three of these methods correctly fire the mutation observer
setTimeout(function() { document.title = 'foo'; }, 1000); // the usual method
setTimeout(function() { document.querySelector('head > title').innerText = 'bar'; }, 2000); // DOM method
setTimeout(function() { $('head > title').text('cheezburger'); }, 3000); // jQuery-only method

The addition of subtree: true was all that was needed to get this working right.

The wrapping of the three title-changing methods in setTimeout calls at the end is just for demonstration purposes; without this the title value changes so quickly that the WebKitMutationObserver doesn't report each change individually, since MutationObserver is designed to accumulate changes over a short period before executing the observer callback.

If one does not need to detect title changes made via the last jQuery-only method, the childList: true property can be omitted from the observer.observe line; only characterData: true is needed to detect the first two title-changing methods.

like image 119
joelpt Avatar answered Oct 26 '22 00:10

joelpt


You have both JQuery and Javascript in your code example. Not sure if your only restricted to JavaScript, but here's how you can do it with jQuery

If you want to trigger the change, take a look at: http://api.jquery.com/trigger/

jQuery

$(document).ready(function () {
    $("title", "head").change(function () {
        console.log("Title has changed");
    });
    //Trigger Change
    $("title","head").text("New Title").trigger("change");
});
like image 32
anAgent Avatar answered Oct 26 '22 00:10

anAgent