最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

angularjs - Reliably change page title in browser history via JavaScript - Stack Overflow

programmeradmin3浏览0评论

Is it possible to change title of the page in the browser history via JavaScript after the page is loaded? Should be cross-browser (of course) and work on browsers that don't support the HTML5 History API, my primary target browser is Chrome.

I've tried a number of approaches, but none of them seem to work reliably. Here is what I've tried last (history.js):

<html>
    <head>
        <title>Standard title</title>
        <script src=".js/master/scripts/bundled-uncompressed/html4%2Bhtml5/native.history.js"></script>
    </head>
    <body>
        <script>
            window.setTimeout(function(){
                document.title = "My custom title";
                History.replaceState({}, "My custom title", window.location.href);
            }, 3000);
        </script>
    </body>
</html>

If I load the history page in Chrom within 3 seconds after page load, I see Standard title, after 3 seconds I get My custom title.

Why I need this: I have a JavaScript-only app (Angular 1) which runs on different environments (dev, test, production). I'd like to display a title like MyApp (<environmentName>), but I don't want to build separate versions of my app per environment. Instead, the app could request the environment info from the backend via AJAX and update the title of the page. All of this works fine (the page title gets updated), but browser history still shows "standard" title.

Is there a way to change title of the page in the browser history as well?

Is it possible to change title of the page in the browser history via JavaScript after the page is loaded? Should be cross-browser (of course) and work on browsers that don't support the HTML5 History API, my primary target browser is Chrome.

I've tried a number of approaches, but none of them seem to work reliably. Here is what I've tried last (history.js):

<html>
    <head>
        <title>Standard title</title>
        <script src="https://rawgit.com/browserstate/history.js/master/scripts/bundled-uncompressed/html4%2Bhtml5/native.history.js"></script>
    </head>
    <body>
        <script>
            window.setTimeout(function(){
                document.title = "My custom title";
                History.replaceState({}, "My custom title", window.location.href);
            }, 3000);
        </script>
    </body>
</html>

If I load the history page in Chrom within 3 seconds after page load, I see Standard title, after 3 seconds I get My custom title.

Why I need this: I have a JavaScript-only app (Angular 1) which runs on different environments (dev, test, production). I'd like to display a title like MyApp (<environmentName>), but I don't want to build separate versions of my app per environment. Instead, the app could request the environment info from the backend via AJAX and update the title of the page. All of this works fine (the page title gets updated), but browser history still shows "standard" title.

Is there a way to change title of the page in the browser history as well?

Share Improve this question edited Dec 10, 2016 at 18:40 Terry Li 17.3k31 gold badges91 silver badges134 bronze badges asked Nov 30, 2016 at 12:14 lexicorelexicore 43.7k17 gold badges139 silver badges225 bronze badges 6
  • Previously I could get it working by just assigning a value to document.title. However, I can no longer reproduce the working behavior, and I'm not sure what requirements it depends on. – John Weisz Commented Dec 5, 2016 at 17:42
  • 1 @JohnWhite I've observed that it works or does not depending on WHEN I actually open the history page - before of after the title is said. – lexicore Commented Dec 5, 2016 at 17:46
  • Then wouldn't it be automatic if you removed the timeout and let it update the title as soon as the page load ? – Romain Commented Dec 6, 2016 at 9:49
  • @RomainFournereau The timeout emulates "we want to change the title at some point of time". – lexicore Commented Dec 6, 2016 at 9:53
  • Noted. I guess you'll have to wait for replaceState() to work with title. Otherwise, I guess a more brutal way would be to somehow make a back and then go right back to the page, updating the title. – Romain Commented Dec 6, 2016 at 10:00
 |  Show 1 more comment

6 Answers 6

Reset to default 3 +200

Short answer: there seems no way you can keep different title records for the same url in Chrome.

Disclaimer: I just stumbled upon this question and had no prior experience about it. Nonetheless, the question was so clear and interesting that I couldn't help but do some experiment:

First of all, I agree that the history records (i.e., the page titles) shown in the history tab are NOT so reliable (maybe a bug or cache).

So I decide that I will look into the database file for Chrome history, for example, using DB Browser for SQLite.

To my surprise, Chrome history keeps only one version (the latest) of title for each url. And when I do History.replaceState({}, "My custom title", window.location.href);, the title does get updated in the database.

However, @Bekim's method wouldn't change the title in the database.

The issue is that the second parameter to replaceState(), the title parameter, is currently ignored by essentially all implementing browsers. However, the third parameter on pushState, url, is taken into consideration. Unfortunately, it does not work with replaceState (at least not in Chrome or Edge, according to my tests).

With that in mind, from client side, you could use one of the following workarounds, whichever your taste is:

history.pushState({}, "", "my-custom-appendix");
history.pushState({}, "", "#my-custom-appendix");

In Chrome, this will create additional entries with a title like http://myurl/my-custom-appendix or http://myurl/#my-custom-appendix (respectively). I believe this is the closest you can get from the client, and the side effect is that you'll get a new history entry in the browser history -- for every visit to your app, you'll essentially see (in increasing timestamp order):

  • Standard Title
  • http://myurl/my-custom-appendix

You'll see the URL as the title even if you have the second parameter set to a non-empty string (at least that's what's happening on my end).


For a more robust approach, you'd need to use a simple server-side preprocessor AFAIK, like PHP.

Firefox 52. Trivial:

document.title = 'CoolCmd';

Chrome 57 requires some magic. This variant also works for Firefox 52. It does not add unnecessary entries to the browser history.

// HACK Do not change the order of these two lines!
history.replaceState(null, '');
document.title = 'CoolCmd';

MS Edge 14.14393 does not allow to change the title of the document in the history. He even does not add to the history the addresses specified by history.pushState()! LOL

I did not test Safari...

Related to angularjs :-

add run method after module :-

.run(function ($rootScope) {

$rootScope.$on('$stateChangeSuccess', function (evt, toState) {
    window.document.title = toState.title + ' - example.com';
});

});

Your state :-

.state('productDetail', {

    title: 'Details of selected product',
    url: '/Detail.html',
    templateUrl: '/product-details.html',
    controller: 'ProductDetailsCtrl'

  })

.state('categoryManager',{

    title: 'Category Manager',
    url: '/category-Manager.html',
    templateUrl: 'categoryManager.html',
    controller: 'categoryManagerCtrl'
   
  });

this will change title according to your state.

That's the easiest thing ever

document.title = "My App " +environmentName;

The history will immediately update the new document title.


to be able to test it positively, try following these few steps.

1st Copy paste the following in your console and execute:

name = '{ "location": ["http://stackoverflow.com/questions/12689408/how-can-jquery-window-location-hash-replace","http://stackoverflow.com/questions/12978739/is-there-a-javascript-api-to-browser-history-information-limited-to-current-dom","http://stackoverflow.com/questions/24653265/angular-browser-history-back-without-reload-previous-page"],"title" : ["Page 1", "Page 2", "Page 3"]}';

    document.title = "Where We've Started";

2nd Copy-Paste the following in your console and execute 3 times

nm = JSON.parse(name);
location = nm.location[0]; 

3rd As soon as the location has loaded, execute the following

nm = JSON.parse(name);
document.title = nm.title[0];

each time increasing the array index as in:

location = nm.location[1];
document.title = nm.title[1];

(the max index is 3, e.g. num 2)
Than click and hold the Back Button to reveal the latest History entries, all sane and updated in order to reflect the new document title.

Warning: If the script is not running after you've stepped back to a given history entry the page title will revert as expected to the existing hard-coded doc title. But since this history control names will be fed by the script in all pages they will also continue to reflect the live document titles provided. This is where people get tricked when moving back to the hard-coded page in history. And think: "damn: something went wrong!"

Figure 1.: End Result of the Demo Code executed on a separate / new window.

You can use document.write() to write correct title to document in first place while it's still loading. But it would require synchronous request to the server:

<head>
  <script>
  (function () {
    // Get title using sync request.
    var title = "Value from server";
    document.write("<title>"+ title + "</title>");
  })();
  </script>
</head>

Page that include snipped above would appear with "Value from server" title in browser history.

发布评论

评论列表(0)

  1. 暂无评论