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?
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.
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");
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With