Dynamisches Ändern des Website-Favicons

347

Ich habe eine Webanwendung, die entsprechend dem aktuell angemeldeten Benutzer gekennzeichnet ist. Ich möchte das Favicon der Seite in das Logo der Handelsmarke ändern, kann jedoch keinen Code oder Beispiele dafür finden um dies zu tun. Hat das schon mal jemand erfolgreich gemacht?

Ich stelle mir ein Dutzend Symbole in einem Ordner vor, und der Verweis auf die zu verwendende Datei favicon.ico wird nur dynamisch zusammen mit der HTML-Seite generiert. Gedanken?

SqlRyan
quelle
40
In einem Favicon gibt es ein Arcade-Spiel .
Corey Trager
Beachten Sie, dass die dynamische Favicon-Implementierung von Chrome fehlerhaft ist und zu viel CPU verbraucht. Siehe code.google.com/p/chromium/issues/detail?id=121333
brillout
6
Der Link für das Arcade-Spiel wurde geändert. Dies ist der richtige.
Basil
Unter stackoverflow.com/questions/6296574/… erfahren Sie, wie Sie das Favicon dynamisch aktualisieren, indem Sie auf ein Vorlagenbild mit Leinwand zeichnen.
behandeln
1
Kleiner Fehler im Codebeispiel in der akzeptierten Antwort. Ich habe nicht genügend Reputationswerte, um Antworten zu kommentieren, daher schreibe ich stattdessen hier. In der letzten Zeile sind die Klammern vertauscht:} ()); sollte lesen })(); Es wäre schön, wenn das Codebeispiel aktualisiert würde, da es höchstwahrscheinlich von anderen kopiert und eingefügt wird.
Goran W

Antworten:

396

Warum nicht?

(function() {
    var link = document.querySelector("link[rel*='icon']") || document.createElement('link');
    link.type = 'image/x-icon';
    link.rel = 'shortcut icon';
    link.href = 'http://www.stackoverflow.com/favicon.ico';
    document.getElementsByTagName('head')[0].appendChild(link);
})();

Firefox sollte damit cool sein.

bearbeitet, um vorhandene Symbole ordnungsgemäß zu überschreiben

Keparo
quelle
2
Ich denke, das kommt dem nahe, wonach ich suche, aber wie würde ich das entsprechende HREF aus der Datenbank erhalten? Ich nehme an, ich muss eine Server-Suche von Javascript aus durchführen, aber ich möchte nicht, dass es zu kompliziert wird. Danke für den Tipp.
SqlRyan
34
Da dies im IE sowieso nicht funktioniert, können Sie es shortcutaus dem relAttribut entfernen . shortcutist eine ungültige IE-proprietäre Linkbeziehung!
Mathias Bynens
8
Sie können genauso gut nach einem vorhandenen Favicon-Link suchen und ihn aktualisieren oder ersetzen.
Keparo
5
Google kann Ihnen das Favicon einer Website geben, indem Sie diese URL verwenden und stackoverflow.com durch die gewünschte Domain ersetzen: s2.googleusercontent.com/s2/favicons?domain=stackoverflow.com
kirb
5
Sollte die Eingabe in der Javascript-Konsole in Chrome funktionieren? Ich kann es nicht dazu bringen, die Favoriten auf verschiedenen Websites auf diese Weise zu ändern.
powerj1984
88

Hier ist ein Code, der in Firefox, Opera und Chrome funktioniert (im Gegensatz zu jeder anderen hier veröffentlichten Antwort). Hier ist eine andere Demo von Code, die auch in IE11 funktioniert . Das folgende Beispiel funktioniert möglicherweise nicht in Safari oder Internet Explorer.

/*!
 * Dynamically changing favicons with JavaScript
 * Works in all A-grade browsers except Safari and Internet Explorer
 * Demo: http://mathiasbynens.be/demo/dynamic-favicons
 */

// HTML5™, baby! http://mathiasbynens.be/notes/document-head
document.head = document.head || document.getElementsByTagName('head')[0];

function changeFavicon(src) {
 var link = document.createElement('link'),
     oldLink = document.getElementById('dynamic-favicon');
 link.id = 'dynamic-favicon';
 link.rel = 'shortcut icon';
 link.href = src;
 if (oldLink) {
  document.head.removeChild(oldLink);
 }
 document.head.appendChild(link);
}

Sie würden es dann wie folgt verwenden:

var btn = document.getElementsByTagName('button')[0];
btn.onclick = function() {
 changeFavicon('http://www.google.com/favicon.ico');
};

Weggabeln oder Demo ansehen .

Mathias Bynens
quelle
Der Chrome-Fehler wurde in Chrome 6 (veröffentlicht am 10. September) behoben, sodass der Chrome-Hack nicht mehr wirklich erforderlich ist. Ich würde dringend empfehlen, ihn nicht zu verwenden, da er die Weiterleitungstaste unterbricht.
Josh3736
Der Chrome-Fehler wurde möglicherweise behoben, ist aber in 14.0.835.187 erneut behoben.
Danorton
Die Demo funktioniert bei Chrome 21 / WinXP nicht.
Hugo
Die Demo funktioniert in Chrome 26 / Win7 nicht für mich. document.head || document.head = document.getElementsByTagName('head')[0]; Uncaught ReferenceError: Invalid left-hand side in assignment
Patrick
2
Dies funktioniert in allen derzeit unterstützten Browsern (IE 11, Edge, FF und Chrome), die nicht mit Safari testen können
Aaron
46

Wenn Sie das folgende HTML-Snippet haben:

<link id="favicon" rel="shortcut icon" type="image/png" href="favicon.png" />

Sie können das Favicon mit Javascript ändern, indem Sie beispielsweise das HREF-Element in diesem Link ändern (vorausgesetzt, Sie verwenden JQuery):

$("#favicon").attr("href","favicon2.png");

Sie können auch ein Canvas-Element erstellen und die HREF als ToDataURL () der Zeichenfläche festlegen, ähnlich wie dies beim Favicon Defender der Fall ist.

fserb
quelle
1
Ich denke, wenn der JS ausgeführt wird, hat der Browser den Link bereits gesehen und versucht zu laden favicon.png. Dies muss möglicherweise serverseitig erfolgen.
CHao
Wenn Sie JQuery nicht verwenden, können Sie das hrefAttribut " #faviconusing" ändern. document.getElementById('favicon').setAttribute('href','favicon2.png') Vielleicht können Sie es Ihrem Beitrag @fserb hinzufügen?
Johannchopin
37

jQuery-Version:

$("link[rel='shortcut icon']").attr("href", "favicon.ico");

oder noch besser:

$("link[rel*='icon']").attr("href", "favicon.ico");

Vanilla JS Version:

document.querySelector("link[rel='shortcut icon']").href = "favicon.ico";

document.querySelector("link[rel*='icon']").href = "favicon.ico";
vorillaz
quelle
@pkExec Eine Kombination aus dieser und der obigen Antwort von keparo (die gewählte Antwort) hat es für mich sowohl in ff als auch in Chrome funktionieren lassen.
MrShmee
17

Ein moderner Ansatz:

const changeFavicon = link => {
  let $favicon = document.querySelector('link[rel="icon"]')
  // If a <link rel="icon"> element already exists,
  // change its href to the given link.
  if ($favicon !== null) {
    $favicon.href = link
  // Otherwise, create a new element and append it to <head>.
  } else {
    $favicon = document.createElement("link")
    $favicon.rel = "icon"
    $favicon.href = link
    document.head.appendChild($favicon)
  }
}

Sie können es dann folgendermaßen verwenden:

changeFavicon("http://www.stackoverflow.com/favicon.ico")
Michał Perłakowski
quelle
11

Das Favicon wird im Head-Tag mit folgenden Elementen deklariert:

<link rel="shortcut icon" type="image/ico" href="favicon.ico">

Sie sollten in der Lage sein, den Namen des gewünschten Symbols in den Ansichtsdaten zu übergeben und in das Head-Tag zu werfen.

Jeff Sheldon
quelle
1
IIRC jedoch respektieren einige Browser (ich schaue in Ihre Richtung, IE) dies manchmal nicht wirklich.
Matthew Schinckel
(Ich fand, dass ich bessere Ergebnisse hatte, wenn ich nur die Symboldatei am richtigen Speicherort hatte und nicht den expliziten Link).
Matthew Schinckel
9

Hier ist ein Code, mit dem ich Opera, Firefox und Chrome dynamische Favicon-Unterstützung hinzufüge. Ich konnte IE oder Safari jedoch nicht zum Laufen bringen. Grundsätzlich erlaubt Chrome dynamische Favoriten, aktualisiert sie jedoch nur, wenn sich der Speicherort der Seite (oder ein iframeusw. darin) ändert, soweit ich das beurteilen kann:

var IE = navigator.userAgent.indexOf("MSIE")!=-1
var favicon = {
    change: function(iconURL) {
        if (arguments.length == 2) {
            document.title = optionalDocTitle}
        this.addLink(iconURL, "icon")
        this.addLink(iconURL, "shortcut icon")

        // Google Chrome HACK - whenever an IFrame changes location 
        // (even to about:blank), it updates the favicon for some reason
        // It doesn't work on Safari at all though :-(
        if (!IE) { // Disable the IE "click" sound
            if (!window.__IFrame) {
                __IFrame = document.createElement('iframe')
                var s = __IFrame.style
                s.height = s.width = s.left = s.top = s.border = 0
                s.position = 'absolute'
                s.visibility = 'hidden'
                document.body.appendChild(__IFrame)}
            __IFrame.src = 'about:blank'}},

    addLink: function(iconURL, relValue) {
        var link = document.createElement("link")
        link.type = "image/x-icon"
        link.rel = relValue
        link.href = iconURL
        this.removeLinkIfExists(relValue)
        this.docHead.appendChild(link)},

    removeLinkIfExists: function(relValue) {
        var links = this.docHead.getElementsByTagName("link");
        for (var i=0; i<links.length; i++) {
            var link = links[i]
            if (link.type == "image/x-icon" && link.rel == relValue) {
                this.docHead.removeChild(link)
                return}}}, // Assuming only one match at most.

    docHead: document.getElementsByTagName("head")[0]}

Um die Favoriten zu ändern, gehen Sie einfach favicon.change("ICON URL") oben beschrieben vor.

(Dank an http://softwareas.com/dynamic-favicons für den Code, auf dem ich diesen basiert habe.)

Kryo
quelle
Der Chrome-Fehler wurde in Chrome 6 (veröffentlicht am 10. September) behoben, sodass der Chrome-Hack nicht mehr wirklich erforderlich ist. Ich würde dringend empfehlen, ihn nicht zu verwenden, da er die Weiterleitungstaste unterbricht.
Josh3736
Chrome hat immer noch den gleichen Fehler, wenn auch unter etwas anderen Umständen als der angegebene spezifische Fehler. code.google.com/p/chromium/issues/detail?id=99549
danorton
4

Ich würde Gregs Ansatz verwenden und einen benutzerdefinierten Handler für favicon.ico erstellen. Hier ist ein (vereinfachter) Handler, der funktioniert:

using System;
using System.IO;
using System.Web;

namespace FaviconOverrider
{
    public class IcoHandler : IHttpHandler
    {
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "image/x-icon";
        byte[] imageData = imageToByteArray(context.Server.MapPath("/ear.ico"));
        context.Response.BinaryWrite(imageData);
    }

    public bool IsReusable
    {
        get { return true; }
    }

    public byte[] imageToByteArray(string imagePath)
    {
        byte[] imageByteArray;
        using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
        {
        imageByteArray = new byte[fs.Length];
        fs.Read(imageByteArray, 0, imageByteArray.Length);
        }

        return imageByteArray;
    }
    }
}

Anschließend können Sie diesen Handler im Abschnitt httpHandlers der Webkonfiguration in IIS6 oder die Funktion "Handlerzuordnungen" in IIS7 verwenden.

Dan
quelle
1
Ich bin eigentlich neugierig, warum dies abgelehnt wurde? Dies ist tatsächlich die beste Antwort, wenn man bedenkt, dass sich alle anderen auf Skripte verlassen, die möglicherweise verfügbar sind oder nicht.
ätherische
1
@ethermal Weil es auf der Serverseite dynamisch aussieht. OP bat den Kunden um Dynamik.
Alexis Wilke
3

Die einzige Möglichkeit, dies für den IE zum Laufen zu bringen, besteht darin, Ihren Webserver so einzustellen, dass Anforderungen für * .ico zum Aufrufen Ihrer serverseitigen Skriptsprache (PHP, .NET usw.) behandelt werden. Richten Sie außerdem * .ico ein, um zu einem einzelnen Skript umzuleiten und dieses Skript die richtige Favicon-Datei liefern zu lassen. Ich bin mir sicher, dass es immer noch einige interessante Probleme mit dem Cache geben wird, wenn Sie in der Lage sein möchten, im selben Browser zwischen verschiedenen Favoriten hin und her zu springen.

Greg
quelle
3

Für diejenigen, die jQuery verwenden, gibt es eine einzeilige Lösung:

$("link[rel*='icon']").prop("href",'https://www.stackoverflow.com/favicon.ico');
Pepelegal
quelle
3

Oder wenn du ein Emoticon willst :)

var canvas = document.createElement("canvas");
canvas.height = 64;
canvas.width = 64;

var ctx = canvas.getContext("2d");
ctx.font = "64px serif";
ctx.fillText("☠️", 0, 64); 

$("link[rel*='icon']").prop("href", canvas.toDataURL());

Requisiten an https://koddsson.com/posts/emoji-favicon/

max4ever
quelle
2

Laut WikiPedia können Sie mithilfe des linkTags im headAbschnitt mit dem Parameter von angeben, welche Favicon-Datei geladen werden soll rel="icon".

Zum Beispiel:

 <link rel="icon" type="image/png" href="/path/image.png">

Ich stelle mir vor, wenn Sie für diesen Anruf dynamische Inhalte schreiben möchten, haben Sie Zugriff auf Cookies, damit Sie Ihre Sitzungsinformationen auf diese Weise abrufen und entsprechende Inhalte präsentieren können.

Möglicherweise haben Sie Probleme mit Dateiformaten (der IE unterstützt angeblich nur das ICO-Format, während die meisten anderen PNG- und GIF-Bilder unterstützen) und möglicherweise mit Caching-Problemen, sowohl im Browser als auch über Proxys. Dies wäre auf die ursprüngliche Absicht von Favicon zurückzuführen, ein Lesezeichen mit dem Mini-Logo einer Site zu markieren.

staticsan
quelle
viel mehr als das. stackoverflow.com/a/45301651/661584 Die FAQs / Informationen auf der Generatorseite werden Sie überraschen - es gibt viel zu diesem Thema.
MemeDeveloper
3
Das Web verändert sich in 9 Jahren sehr.
Staticsan
2

Ja absolut möglich

  • Verwenden Sie einen Querystring nach favicon.ico (und anderen - siehe Antwortlink unten).
  • Stellen Sie einfach sicher, dass der Server auf die "someUserId" mit der richtigen Image-Datei antwortet (dies können statische Routing-Regeln oder dynamischer serverseitiger Code sein).

z.B

<link rel="shortcut icon" href="/favicon.ico?userId=someUserId">

Dann was serverseitige Sprache / framework Sie verwenden sollten leicht in der Lage sein , um die finden Datei auf dem userId basiert und es in servieren Antwort auf diese Anfrage .

Aber um Favicons richtig zu machen (es ist eigentlich ein sehr komplexes Thema ), lesen Sie bitte die Antwort hier https://stackoverflow.com/a/45301651/661584

Viel einfacher als alle Details selbst herauszuarbeiten.

Genießen.

MemeDeveloper
quelle
Ja, der Link ist gut. Ich denke, dass der Hauptgrund, warum diese Antworten im IE nicht funktionieren, darin besteht, dass sie nicht dieses Standardsymbol verwenden <link>, sondern stattdessen nach der apple-touch-iconoder einer anderen solchen Variante suchen .
Alexis Wilke
1

Ich benutze favico.js in meinen Projekten.

Sie können das Favicon in eine Reihe vordefinierter und auch benutzerdefinierter Formen ändern.

Intern wird es canvasfür das Rendern und die base64Daten-URL für die Symbolcodierung verwendet.

Die Bibliothek hat auch nette Funktionen: Symbolabzeichen und Animationen; angeblich kannst du das webcam video sogar in das icon streamen :)

Oscar Nevarez
quelle
Der Link und die Bibliothek sind sehr nützlich. Bitte geben Sie eine Beschreibung der Funktionsweise an, damit dies auch eine gültige Antwort auf die angegebene Frage ist.
Dima Tisnek
1
Danke @DimaTisnek. Ich habe meine Antwort aktualisiert.
Oscar Nevarez
0

Ich benutze diese Funktion ständig, wenn ich Websites entwickle ... damit ich auf einen Blick sehen kann, auf welcher Registerkarte Local, Dev oder Prod ausgeführt werden.

Jetzt, da Chrome SVG-Favicons unterstützt, wird es viel einfacher.

Tampermonkey-Skript

Unter https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360f finden Sie ein Tampermonkey-Skript, das auf eine Demo-Site verweist, die ich unter https://elliz.github.io/svg-favicon/ erstellt habe.

Grundcode

Angepasst an eine andere Antwort ... könnte verbessert werden, aber gut genug für meine Bedürfnisse.

(function() {
    'use strict';

    // play with https://codepen.io/elliz/full/ygvgay for getting it right
    // viewBox is required but does not need to be 16x16
    const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
      <circle cx="8" cy="8" r="7.2" fill="gold" stroke="#000" stroke-width="1" />
      <circle cx="8" cy="8" r="3.1" fill="#fff" stroke="#000" stroke-width="1" />
    </svg>
    `;

    var favicon_link_html = document.createElement('link');
    favicon_link_html.rel = 'icon';
    favicon_link_html.href = svgToDataUri(svg);
    favicon_link_html.type = 'image/svg+xml';

    try {
        let favicons = document.querySelectorAll('link[rel~="icon"]');
        favicons.forEach(function(favicon) {
            favicon.parentNode.removeChild(favicon);
        });

        const head = document.getElementsByTagName('head')[0];
        head.insertBefore( favicon_link_html, head.firstChild );
    }
    catch(e) { }

    // functions -------------------------------
    function escapeRegExp(str) {
        return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
    }

    function replaceAll(str, find, replace) {
        return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
    }

    function svgToDataUri(svg) {
        // these may not all be needed - used to be for uri-encoded svg in old browsers
        var encoded = svg.replace(/\s+/g, " ")
        encoded = replaceAll(encoded, "%", "%25");
        encoded = replaceAll(encoded, "> <", "><"); // normalise spaces elements
        encoded = replaceAll(encoded, "; }", ";}"); // normalise spaces css
        encoded = replaceAll(encoded, "<", "%3c");
        encoded = replaceAll(encoded, ">", "%3e");
        encoded = replaceAll(encoded, "\"", "'"); // normalise quotes ... possible issues with quotes in <text>
        encoded = replaceAll(encoded, "#", "%23"); // needed for ie and firefox
        encoded = replaceAll(encoded, "{", "%7b");
        encoded = replaceAll(encoded, "}", "%7d");
        encoded = replaceAll(encoded, "|", "%7c");
        encoded = replaceAll(encoded, "^", "%5e");
        encoded = replaceAll(encoded, "`", "%60");
        encoded = replaceAll(encoded, "@", "%40");
        var dataUri = 'data:image/svg+xml;charset=UTF-8,' + encoded.trim();
        return dataUri;
    }

})();

Fügen Sie einfach Ihr eigenes SVG (möglicherweise mit Jake Archibalds SVGOMG gereinigt, wenn Sie ein Tool verwenden) in die Konstante oben ein. Stellen Sie sicher, dass es quadratisch ist (mithilfe des viewBox-Attributs) und Sie können loslegen.

Ruskin
quelle