'How to listen for changes to the title element?

In Javascript, is there a technique to listen for changes to the title element?



Solution 1:[1]

2022 Update

Mutation Observers are unequivocally the way to go now (see Vladimir Starkov's answer), with no need for fallbacks to the older APIs mentioned below. Furthermore, DOMSubtreeModified should be actively avoided now.

I'm leaving the remainder of this answer here for posterity.

2010 Answer

You can do this with events in most modern browsers (notable exceptions being all versions of Opera and Firefox 2.0 and earlier). In IE you can use the propertychange event of document and in recent Mozilla and WebKit browsers you can use the generic DOMSubtreeModified event. For other browsers, you will have to fall back to polling document.title.

Note that I haven't been able to test this in all browsers, so you should test this carefully before using it.

2015 Update

Mutation Observers are the way to go in most browsers these days. See Vladimir Starkov's answer for an example. You may well want some of the following as fallback for older browsers such as IE <= 10 and older Android browsers.

function titleModified() {
    window.alert("Title modifed");
}

window.onload = function() {
    var titleEl = document.getElementsByTagName("title")[0];
    var docEl = document.documentElement;

    if (docEl && docEl.addEventListener) {
        docEl.addEventListener("DOMSubtreeModified", function(evt) {
            var t = evt.target;
            if (t === titleEl || (t.parentNode && t.parentNode === titleEl)) {
                titleModified();
            }
        }, false);
    } else {
        document.onpropertychange = function() {
            if (window.event.propertyName == "title") {
                titleModified();
            }
        };
    }
};

Solution 2:[2]

There's not a built-in event. However, you could use setInterval to accomplish this:

var oldTitle = document.title;
window.setInterval(function()
{
    if (document.title !== oldTitle)
    {
        //title has changed - do something
    }
    oldTitle = document.title;
}, 100); //check every 100ms

Solution 3:[3]

This's my way, in a closure and check in startup

(function () {
    var lastTitle = undefined;
    function checkTitle() {
        if (lastTitle != document.title) {
            NotifyTitleChanged(document.title); // your implement
            lastTitle = document.title;
        }
        setTimeout(checkTitle, 100);
    };
    checkTitle();
})();

Solution 4:[4]

Don't forget to remove listener when not needed anymore.

Vanilla JS:

const observer = new MutationObserver((mutations) => {
     console.log(mutations[0].target.text);
});

observer.observe(document.querySelector("title"), {
  subtree: true,
  characterData: true,
  childList: true,
})

observer.disconnect() // stops looking for changes

Or if you use React which is really neat with removing listeners, I wrote this hook:

React.useEffect(() => {
    const observer = new MutationObserver(mutations => {
       console.log(mutations[0].target.text)
    })
    observer.observe(document.querySelector("title"), {
        subtree: true,
        characterData: true,
        childList: true,
    })
    return () => observer.disconnect()
}, [defaultTitle, notificationTitle])

Solution 5:[5]

const observer = new MutationObserver(([{ target }]) =>
  // Log change
  console.log(target.text),
)

observer.observe(document.querySelector('title'), {
  childList: true,
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ShZ
Solution 3
Solution 4 Gabriel Petersson
Solution 5 Wenfang Du