9

I'm opening a new window into which I'm injecting HTML for both the body and the head. The problem is in the head section: the HTML includes both the title and the favicon but the favicon doesn't show. This is the code and the jsFiddle: https://jsfiddle.net/ufnjspgc/

function Start() {

  $('#TheButton').click(function() {

    var TheHeadHTML = '<link href="' + window.location.protocol + '//' + window.location.host + '/favicon.ico" rel="icon" type="image/x-icon">';
    TheHeadHTML = TheHeadHTML + '<title>Title Works</title>';

    var TheNewWindow = window.open();

    $(TheNewWindow.document.head).html(TheHeadHTML);
  });
}

$(Start);

How do you make the favicon appear in the new window?

halfer
  • 19,824
  • 17
  • 99
  • 186
frenchie
  • 51,731
  • 109
  • 304
  • 510

7 Answers7

7

You can open a new window using a data URI. Here's the code:

<input type="button" value="test" id="TheButton" />

function Start() {

  $('#TheButton').click(function() {
    var TheNewWindow = window.open("data:text/html;charset=utf8,<html><head><link href='" + window.location.protocol + "//" + window.location.host + "/favicon.ico' rel='icon' type='image/x-icon'><title>Title Works</title></head><body></body></html>");
  });
}

$(Start);

And the fiddle.

Basically, data URIs allow you to specify the content in the URL itself such that it doesn't need to go to a server, or, in your case, to the "about:blank" resource browsers (must) have. "about:blank" can cause a lot of problems when scripting because of cross-origin and other concerns.

As noted by @ConnorsFan, this technique does not work in IE. As indicated in this question by Diego Mijelshon, IE does not allow navigation to a data URI, and thus it cannot be used as the URL for a new window. Seems to work fine in recent versions of Chrome and Firefox. I'm afraid I don't have a copy of Safari on which to test.

Community
  • 1
  • 1
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
  • +1 for this very nice solution! The fiddle does not seem to work in IE11 however. It may be related to the limitation for MS browsers, mentioned in your [data URI reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs). – ConnorsFan Oct 28 '16 at 22:00
  • Good catch @ConnorsFan, looks like IE only allows data URIs for specific types too. I'll update the answer. – Heretic Monkey Oct 28 '16 at 22:09
  • At first glance it works but then it seems that if you create a new window with this technique you can't change the body, can't seem to find a reference to it. Updated fiddle: https://jsfiddle.net/ufnjspgc/6/ – frenchie Oct 29 '16 at 19:33
  • Well, that fiddle tries to add a div to the head, but changing it to body doesn't help... If you can, you could just push all of the HTML at once. – Heretic Monkey Oct 31 '16 at 13:51
2

If the favicon is from your own Web site, you can create a print.html template page that contains the favicon link (with an id attribute):

<!DOCTYPE html>
<html>
<head>
    <link id="favicon" rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
</body>
</html>

When the button is clicked, you open that page and inject the additional content in the head and body sections. According to my tests, the presence of the favicon link in the DOM is a good indicator to determine when the page content can be modified. For Chrome and Firefox, the changes can be made in $(wnd).load(). For Internet Explorer 11, they can be made in $(wnd.document).ready().

$("#btnOpenWindow").click(function () {
    var done = false;

    // Open the window with the empty page
    var wnd = window.open("print.html");

    // For Chrome and Firefox
    $(wnd).load(function () {
        injectContent();
    });

    // For Internet Explorer
    $(wnd.document).ready(function () {
        injectContent();
    });

    function injectContent() {
        // If the favicon link is loaded in the DOM, the content can be modified
        if (!done && $("#favicon", wnd.document).length > 0) {
            done = true;
            $("head", wnd.document).append("<title>The window title</title>");
            $("body", wnd.document).append("<h1>Main title</h1>");
            ...
        }
    }
});

If you really need to modify the favicon of the new window, you can use the same method as above, with the following changes:

<link id="favicon" rel="shortcut icon" type="image/x-icon" />
function injectContent() {
    if (!done) {
        var $favicon = $("#favicon", wnd.document);
        if ($favicon.length > 0) {
            done = true;
            var faviconUrl = window.location.protocol + "//" + window.location.host + "/favicon.ico";
            $favicon.attr("href", faviconUrl);
            $("head", wnd.document).append("<title>The window title</title>");
            $("body", wnd.document).append("<h1>Main title</h1>");
            ...
        }
    }
}
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
0

As an alternative, and alhough this is a bit heavy, you can set the favicon via JavaScript by injecting code in TheHeadHTML. If you don't want to bother with JS/favicon nitty-gritty, you can use a library such as favico.js.

philippe_b
  • 38,730
  • 7
  • 57
  • 59
  • Tried that in jsFiddle but it's not working and it's not working for my site either: https://jsfiddle.net/ufnjspgc/2/ – frenchie Oct 23 '16 at 00:24
0

You should dynamically change the URL using a URL parameter as a cache busting method. I have seen browsers hold onto favicons for a long time even after the icon had been changed without a cache busting method.

'<link href="' + window.location.protocol + '//' + window.location.host + '/favicon.ico?v=' + Math.round(Math.random() * 100000) + '" rel="icon" type="image/x-icon">';
0
$(TheNewWindow.document.head).append(TheHeadHTML);
Aimeé RP
  • 114
  • 1
0

here's an answer which i think would help you

html :

<a id="link" href="#">Click me</a>

javaScript - jQuery (actually)

$('#link').click(function(){
  var goto = window.open('http://stackoverflow.com/questions/40177033/how-to-make-the-favicon-appear-in-a-new-window');
});
Zac
  • 1,305
  • 3
  • 17
  • 28
0

I possible, Inject your html any way you like, however in the window.open(); give a valid url to an empty page on your server window.open("/myTinyPage.html");.This way you can still inject your html hover the page comes from the server and has a favicon. You pay ping time, however code is simple.

O_Z
  • 1,515
  • 9
  • 11