Changing website favicon dynamically

前端 未结 15 1307
温柔的废话
温柔的废话 2020-11-22 02:17

I have a web application that\'s branded according to the user that\'s currently logged in. I\'d like to change the favicon of the page to be the logo of the private label,

相关标签:
15条回答
  • 2020-11-22 02:32

    The favicon is declared in the head tag with something like:

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

    You should be able to just pass the name of the icon you want along in the view data and throw it into the head tag.

    0 讨论(0)
  • 2020-11-22 02:34

    There is a single line solution for those who use jQuery:

    $("link[rel*='icon']").prop("href",'https://www.stackoverflow.com/favicon.ico');
    
    0 讨论(0)
  • 2020-11-22 02:38

    jQuery Version:

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

    or even better:

    $("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";
    
    0 讨论(0)
  • 2020-11-22 02:38

    I use this feature all the time when developing sites ... so I can see at-a-glance which tab has local, dev or prod running in it.

    Now that Chrome supports SVG favicons it makes it a whole lot easier.

    Tampermonkey Script

    Have a gander at https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360f for a tampermonkey script that points to a demo site I chucked up at https://elliz.github.io/svg-favicon/

    Basic code

    Adapted this from another answer ... could be improved but good enough for my needs.

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

    Just pop your own SVG (maybe cleaned with Jake Archibald's SVGOMG if you're using a tool) into the const at the top. Make sure it is square (using the viewBox attribute) and you're good to go.

    0 讨论(0)
  • 2020-11-22 02:42

    The only way to make this work for IE is to set you web server to treat requests for *.ico to call your server side scripting language (PHP, .NET, etc). Also setup *.ico to redirect to a single script and have this script deliver the correct favicon file. I'm sure there is still going to be some interesting issues with cache if you want to be able to bounce back and forth in the same browser between different favicons.

    0 讨论(0)
  • 2020-11-22 02:43

    A more modern approach:

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

    You can then use it like this:

    changeFavicon("http://www.stackoverflow.com/favicon.ico")
    
    0 讨论(0)
提交回复
热议问题