18

Is it possible to make document.title (<head><title> .. </title></head>) impossible to change for Javascript ?

My problem is that iny my project there are some javascripts that change document.title every 1 second and I want title to stay the same. Unfortuantely I am not able to change or remove those JS files. I've tried a to think of workaround, something like that :

function checkTitle() {
if(document.title != oldTitle)
document.title = oldTitle;
}
setInterval(checkTitle(), 100);

It seems like a good idea, BUT unfortuantely there I have also counter which displays timer on my site. My whole code looks like this :

var ticks = 0;

function update() {
    if(ticks % 1000 == 0) {
    ...update timer and some other stuff...
    }
    ticks+=100;
    if(document.title != oldTitle)
    document.title = oldTitle;
}
setInterval(update, 100);

Such code after +- 100 seconds is beggining to slow down and my timer definitely is not updated every 1 second.

So the question is : Is it possible to make html element (..) impossible to change for javascript, if not, is there any workaround for my problem ?

Thanks in advance.

Nick
  • 1,417
  • 1
  • 14
  • 21
pzeszko
  • 1,989
  • 18
  • 29
  • 10
    why cant you remove the part that changes document.title exactly? –  Jan 08 '15 at 19:05
  • 1
    Interesting question. What's the logic behind changing the title of the page/preventing this change? Out of curiosity more than anything. – Tim Lewis Jan 08 '15 at 19:05
  • you can listen for propertychange as mentioned at http://stackoverflow.com/questions/2497200/how-to-listen-for-changes-to-the-title-element – Vishal Seth Jan 08 '15 at 19:07
  • It's because my project is done using Liferay Portal. Liferay adds to every pages some JS files to control some session things, not sure exactly. Actually I've heard that there is a way how to upate those files but it's not easy and at the moment I'm waiting for response on Liferay forum - but it doesn't look like someone is going to respond. – pzeszko Jan 08 '15 at 19:07
  • 3
    like this (does have side effects) -> **http://jsfiddle.net/u4334pky/1/** – adeneo Jan 08 '15 at 19:08
  • Why not just overwritting update() method? – A. Wolff Jan 08 '15 at 19:10
  • @A.Wolff what do you mean ? The function which updates document.title (which I want to be stopped) is in JS files that I cannot change. – pzeszko Jan 08 '15 at 19:12
  • @pzeszko `function update(){}` but that's depend of update method scope, i have no idea what is `Liferay` :) – A. Wolff Jan 08 '15 at 19:14
  • @TimLewis After some time when user loggs in to my portal there should be a warning message that the session is about to expire. It is done by those JS files I cannot touch. Also in document.title there show up a counter which count down to 0. Now, I hide this message (using CSS) and then display it just 5 minutes before expiration. It's easy but unfortuantely I cannot figure out how to prevent those JS files to update my document.title, which I want to hold a portal name. – pzeszko Jan 08 '15 at 19:16
  • A counter? So you're changing the document title yourself, and using it as a counter, and you just want certain scripts to not be able to access document.title? If so, that probably can't be done, it's either or, afaik. Why would you use `document.title` as a counter to begin with ? – adeneo Jan 08 '15 at 19:19
  • No no - I know it's confusing because of the Liferay thing. I set `document.title` to be a portal name and I don't change it. Now, those JS files , let's say 10 minutes after log in show warning message about expiry AND they set document.title as a counter, which count down to 0. – pzeszko Jan 08 '15 at 19:23
  • @pzeszko I see. That's an odd programing choice tbh. I know some sites like facebook flash messages at you via the title, and I've always found it weird. Adeneo has a good solution for this if you want to completely stop it. But still, interesting question :P – Tim Lewis Jan 08 '15 at 19:23
  • Yes, if you just want to lock the title property from everyone, forever (or at least until you redefine it), the below answer would work. – adeneo Jan 08 '15 at 19:33

2 Answers2

24

This probably has some side effects, but I'm not sure what exactly, but you can redefine the title property and make it non-writable, which would be better than sealing or freezing the entire document as it only affects the title

Object.defineProperty(document, 'title', {
  enumerable: false,
  configurable: false,
  writable: false,
  value: document.title
});

FIDDLE

This should work in all browser from IE9 and up, and maybe IE8, which I haven't tested, but I think only DOM nodes can be changed in IE8, and not sure if document counts ?

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Wow, it's super-interesting. Also curious about side effects, but I can't think of any! Document.title seems like unrelevant element so it should break anything. I'll check this solution and came back to you - thanks. – pzeszko Jan 08 '15 at 19:20
  • I can't really think of any side effects either, it's just that locking document properties doesn't really sound like something you would generally want to do, so I addded a "disclaimer" ? – adeneo Jan 08 '15 at 19:21
  • I've decied to mark it as accepted answer before really testing in my project because it doesn't look that obvious and I didn't see it elsewhere : thank you. Just to be absolutely certain : if I put this code in a JS which is added to every page (just like those JS files which want to change title) the title should stay the same and untouchable? – pzeszko Jan 08 '15 at 19:30
  • @pzeszko - it should, and it will, as long as the code above runs before the scripts trying to change the title – adeneo Jan 08 '15 at 19:32
  • 1
    This assumes that you get to run code first but given that it's as good as you can get. An extension for instance or a determined user can easily override this. – Benjamin Gruenbaum Jan 08 '15 at 19:36
  • @adeneo Even if you're after the scripts changing the title, you can reset it to what it should be right before running the locking. – Riking Jan 09 '15 at 00:10
  • @Riking - indeed you could, it would just be a matter of changing the last setting above (value) to whatever the title is supposed to be. – adeneo Jan 09 '15 at 00:26
  • Yes, exactly. In my project I didn't even have to do that : those JS scripts which change the title start working after 10 minutes after logging to my portal. Works like a charm ! – pzeszko Jan 10 '15 at 11:50
1

You can bind the following events to your title tag to prevent changing itself:

$(document).ready(function() {
    $('title').bind('DOMSubtreeModified propertychange', function() {
        var title = $('title');
        if(title.text() != 'old title')
        {
            alert('title changed');
        }
    });

    $('a').bind('click', function() {
        $('title').text('new title');
    });
});
Tyr
  • 2,810
  • 1
  • 12
  • 21