Modifica favicon del sito Web in modo dinamico


347

Ho un'applicazione web con il marchio in base all'utente attualmente connesso. Vorrei cambiare la favicon della pagina in modo che diventi il ​​logo dell'etichetta privata, ma non riesco a trovare alcun codice o esempio di come per farlo. Qualcuno lo ha già fatto con successo?

Sto immaginando di avere una dozzina di icone in una cartella, e il riferimento a quale file favicon.ico da usare è appena generato dinamicamente insieme alla pagina HTML. Pensieri?


40
C'è un gioco arcade in una favicon.
Corey Trager

Tieni presente che l'implementazione della favicon dinamica di Chrome è difettosa e utilizza troppa CPU. Vedi code.google.com/p/chromium/issues/detail?id=121333
brillout

6
Il link per il gioco arcade è cambiato. Questo è quello corretto.
Basilio

Vedi stackoverflow.com/questions/6296574/… su come aggiornare dinamicamente la favicon disegnando sulla parte superiore di un'immagine modello con tela.
gestire il

1
Piccolo bug nell'esempio di codice fornito nella risposta accettata. Non ho un punteggio di reputazione sufficiente per commentare le risposte, quindi scrivo qui invece. L'ultima riga ha le parentesi scambiate:} ()); dovresti leggere })(); Sarebbe bello che l'esempio di codice venga aggiornato poiché è molto probabilmente copiato e incollato da altri.
Goran W

Risposte:


396

Perchè no?

(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 dovrebbe essere interessante.

modificato per sovrascrivere correttamente le icone esistenti


2
Sto pensando che questo sia vicino a quello che sto cercando, ma come otterrei l'HREF appropriato dal database. Suppongo che dovrò fare una ricerca del server da JavaScript, ma non voglio che diventi troppo complicato. Grazie per il consiglio.
SqlRyan,

34
Poiché ciò non funziona in IE, puoi rimuoverlo shortcutdall'attributo rel. shortcutè una relazione di collegamento proprietaria di IE non valida!
Mathias Bynens,

8
Potresti anche cercare un collegamento favicon esistente e aggiornarlo o sostituirlo.
Keparo,

5
Google può darti la favicon di un sito usando questo URL, sostituendo stackoverflow.com con il dominio che desideri: s2.googleusercontent.com/s2/favicons?domain=stackoverflow.com
kirb

5
Inserendo questo nella console Javascript in Chrome dovrebbe funzionare? Non riesco a cambiare le favicon su vari siti in quel modo.
powerj1984,

88

Ecco del codice che funziona in Firefox, Opera e Chrome (a differenza di ogni altra risposta pubblicata qui). Ecco una diversa demo di codice che funziona anche in IE11 . Il seguente esempio potrebbe non funzionare in Safari o 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);
}

Lo useresti quindi come segue:

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

Biforcarsi o visualizzare una demo .


Il bug di Chrome è stato corretto in Chrome 6 (rilasciato il 10 settembre), quindi l'hack di Chrome non è più davvero necessario - in effetti, consiglio vivamente di non usarlo poiché si rompe il pulsante di avanzamento.
josh3736,

Il bug di Chrome potrebbe essere stato corretto, ma è stato nuovamente risolto in 14.0.835.187.
Danorton,

La demo non funziona per me con Chrome 21 / WinXP.
Hugo,

La demo non funziona per me in Chrome 26 / Win7. document.head || document.head = document.getElementsByTagName('head')[0]; Uncaught ReferenceError: Invalid left-hand side in assignment
Patrick,

2
Funziona con tutti i browser attualmente supportati (IE 11, Edge, FF e Chrome) incapaci di testare con Safari
Aaron

46

Se hai il seguente frammento HTML:

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

Puoi cambiare la favicon usando Javascript cambiando l'elemento HREF su questo link, per esempio (supponendo che stai usando JQuery):

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

Puoi anche creare un elemento Canvas e impostare l'HREF come ToDataURL () del canvas, proprio come fa il Favicon Defender .


1
Penserei che quando JS funzionerà, il browser avrà già visto il collegamento e tentato di caricare favicon.png. Potrebbe essere necessario eseguire questa operazione sul lato server.
cHao,

Se non si utilizza JQuery, è possibile modificare l' hrefattributo #faviconutilizzando document.getElementById('favicon').setAttribute('href','favicon2.png') Forse si può aggiungere al tuo @fserb post?
johannchopin,

37

Versione jQuery:

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

o anche meglio:

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

Vanilla JS versione:

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

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

@pkExec Una combinazione di questo e la risposta di keparo sopra (la risposta scelta) mi ha fatto funzionare sia in ff che in chrome per me.
MrShmee,

17

Un approccio più moderno:

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)
  }
}

Puoi quindi usarlo in questo modo:

changeFavicon("http://www.stackoverflow.com/favicon.ico")

11

La favicon è dichiarata nel tag head con qualcosa del tipo:

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

Dovresti essere in grado di passare semplicemente il nome dell'icona desiderata nei dati della vista e gettarlo nel tag head.


1
IIRC, tuttavia, alcuni browser (sto guardando nella tua direzione, IE) a volte non lo rispettano.
Matthew Schinckel,

(Ho scoperto di avere risultati migliori solo con il file icona nella posizione giusta, piuttosto che il link esplicito).
Matthew Schinckel,

9

Ecco un po 'di codice che uso per aggiungere il supporto dinamico favicon a Opera, Firefox e Chrome. Tuttavia, non sono riuscito a far funzionare IE o Safari. Fondamentalmente Chrome consente favicon dinamici, ma li aggiorna solo quando la posizione della pagina (o iframeecc.) Cambia per quanto posso dire:

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]}

Per cambiare le favicon, basta favicon.change("ICON URL")usare quanto sopra.

(crediti a http://softwareas.com/dynamic-favicons per il codice su cui ho basato questo.)


Il bug di Chrome è stato corretto in Chrome 6 (rilasciato il 10 settembre), quindi l'hack di Chrome non è più davvero necessario - in effetti, consiglio vivamente di non usarlo poiché si rompe il pulsante di avanzamento.
josh3736,

Chrome ha ancora lo stesso bug, anche se in circostanze leggermente diverse rispetto al bug specifico notato. code.google.com/p/chromium/issues/detail?id=99549
danorton

4

Vorrei usare l'approccio di Greg e creare un gestore personalizzato per favicon.ico Ecco un gestore (semplificato) che funziona:

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;
    }
    }
}

Quindi è possibile utilizzare quel gestore nella sezione httpHandlers della configurazione Web in IIS6 o utilizzare la funzione "Mapping gestori" in IIS7.


1
in realtà sono curioso di sapere perché questo è stato downvoted? questa è in realtà la risposta migliore considerando che tutti gli altri si basano su script che potrebbero essere o meno disponibili.
etereo

1
@ethermal Perché sembra dinamico sul lato server. OP stava chiedendo dinamismo da parte del cliente.
Alexis Wilke,

3

L'unico modo per farlo funzionare per IE è impostare il tuo server web in modo che gestisca le richieste per * .ico di chiamare il tuo linguaggio di scripting lato server (PHP, .NET, ecc.). Installa anche * .ico per reindirizzare a un singolo script e fare in modo che questo script fornisca il file favicon corretto. Sono sicuro che ci saranno ancora alcuni problemi interessanti con la cache se vuoi essere in grado di rimbalzare avanti e indietro nello stesso browser tra diversi favicon.


3

Esiste una soluzione a linea singola per coloro che usano jQuery:

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

3

O se vuoi un'emoticon :)

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());

Puntelli su https://koddsson.com/posts/emoji-favicon/


2

Secondo WikiPedia , puoi specificare quale file favicon caricare usando il linktag nella headsezione, con un parametro direl="icon" .

Per esempio:

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

Immagino che se volessi scrivere alcuni contenuti dinamici per quella chiamata, avresti accesso ai cookie in modo da poter recuperare le informazioni sulla sessione in quel modo e presentare il contenuto appropriato.

È possibile che si verifichino errori nei formati di file (IE supporta solo il suo formato .ICO, mentre la maggior parte degli altri supporta immagini PNG e GIF) e possibilmente problemi di memorizzazione nella cache, sia sul browser che tramite i proxy. Ciò sarebbe dovuto all'idea originale di favicon, in particolare, per contrassegnare un segnalibro con il mini-logo di un sito.


molto di più. stackoverflow.com/a/45301651/661584 le domande frequenti / informazioni sul sito del generatore ti sorprenderanno - c'è molto su questo argomento.
MemeDeveloper il

3
Il web cambia molto in 9 anni.
staticsan

2

Sì totalmente possibile

  • Usa una stringa di querystring dopo favicon.ico (e altri collegamenti ai file: vedere il collegamento delle risposte di seguito)
  • Assicurati semplicemente che il server risponda a "someUserId" con il file di immagine corretto (che potrebbe essere regole di routing statico o codice lato server dinamico ).

per esempio

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

Quindi, qualunque sia la lingua / il framework lato server che usi, dovrebbe essere facilmente in grado di trovare il file in base all'Id utente e servirlo in risposta a quella richiesta .

Ma per fare correttamente le favicon (in realtà è un argomento davvero complesso ), vedi la risposta qui https://stackoverflow.com/a/45301651/661584

Molto più facile che elaborare tutti i dettagli da soli.

Godere.


Sì, il link è buono. Penso che il motivo principale per cui queste risposte non funzionano in IE sia perché non usano quell'icona predefinita <link>, ma cercano invece apple-touch-icono qualche altra variante del genere.
Alexis Wilke,

1

Uso favico.js nei miei progetti.

Permette di cambiare la favicon in una gamma di forme predefinite e anche personalizzate.

Internamente utilizza canvasper il rendering e base64l'URL dei dati per la codifica delle icone.

La biblioteca ha anche delle belle caratteristiche: badge e animazioni di icone; presumibilmente, puoi persino trasmettere il video della webcam nell'icona :)


Il link e la libreria sono molto utili, si prega di fornire una descrizione di come funziona in modo che anche questa diventi una risposta valida alla domanda come indicato.
Dima Tisnek,

1
Grazie @DimaTisnek. Ho aggiornato la mia risposta.
Oscar Nevarez,

0

Uso questa funzione in ogni momento durante lo sviluppo di siti ... in modo da poter vedere a colpo d'occhio quale scheda contiene localmente, sviluppo o prod.

Ora che Chrome supporta i favicon SVG lo rende molto più semplice.

Tampermonkey Script

Dai un'occhiata a https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360f per uno script tampermonkey che punta a un sito demo che ho aperto https://elliz.github.io/svg-favicon/

Codice di base

Adattato questo da un'altra risposta ... potrebbe essere migliorato ma abbastanza buono per le mie esigenze.

(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;
    }

})();

Basta inserire il proprio SVG (magari ripulito con SVGOMG di Jake Archibald se si utilizza uno strumento) nella const in alto. Assicurati che sia quadrato (usando l'attributo viewBox) e sei a posto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.