Динамічно змінюється веб-сайт Favicon


347

У мене є веб-додаток, який брендується відповідно до користувача, який зараз увійшов. Я хотів би змінити фаворит сторінки на логотип приватної етикетки, але я не можу знайти жодного коду чи будь-яких прикладів того, як зробити це. Хтось успішно робив це раніше?

Я зображую, що в папці є десяток піктограм, і посилання на який файл favicon.ico використовувати, просто генерується динамічно разом із HTML-сторінкою. Думки?



Зауважте, що динамічна реалізація веб-переглядача Chrome є помилковою та використовує занадто багато процесора. Дивіться code.google.com/p/chromium/isissue/detail?id=121333
brillout

6
Змінено посилання на аркадну гру. Це правильний.
Василь

Див. Stackoverflow.com/questions/6296574/… про те, як динамічно оновлювати фавікон, намалювавши зверху зображення шаблону полотном.
обробляти

1
Невелика помилка у прикладі коду, надана у прийнятій відповіді. Я не маю достатньої оцінки репутації, щоб коментувати відповіді, отже, натомість пишу тут. Останній рядок змінює круглі дужки:} ()); слід читати}) (); Було б непогано, щоб приклад коду оновлювався, оскільки його, швидше за все, копіюють та вставляють інші.
Goran W

Відповіді:


396

Чому ні?

(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 з ним повинен бути крутим.

редагується, щоб правильно перезаписати наявні значки


2
Я думаю, що це близько до того, що я шукаю, але як би я отримати відповідний HREF з бази даних. Я вважаю, що мені доведеться зробити пошук сервера з javascript, але я не хочу, щоб він став надто складним. Дякую за пораду.
SqlRyan

34
Оскільки це все одно не працює в IE, його можна видалити shortcutз relатрибута. shortcutє недійсним співвідношенням IE-майнового зв’язку!
Mathias Bynens

8
Ви можете так само легко знайти існуючий посилання на фавікон та оновити його або замінити.
кепаро

5
Google може надати вам фавікон сайту, скориставшись цією URL-адресою, замінивши stackoverflow.com потрібним доменом: s2.googleusercontent.com/s2/favicons?domain=stackoverflow.com
kirb

5
Чи слід це вводити на консолі Javascript у Chrome? Я не можу змусити це змінити фаворити на різних сайтах таким чином.
powerj1984

88

Ось код, який працює в Firefox, Opera та Chrome (на відміну від будь-якого іншого відповіді, розміщеного тут). Ось інша демонстрація коду, яка працює і в IE11 . Наступний приклад може не працювати в Safari або 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);
}

Потім ви використовуєте його наступним чином:

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

Вилазити геть або перегляньте демонстраційну версію .


Помилка Chrome була виправлена в Chrome 6 (випущений Вересня 10), так що зламати Chrome не дійсно потрібно більше - насправді, я настійно рекомендую не використовувати його , так як він ламає кнопку вперед.
josh3736

Помилка Chrome, можливо, була виправлена, але вона знову зламана в 14.0.835.187.
Данортон

Демо не працює для мене з Chrome 21 / WinXP.
Гюго

Демо для мене не працює в Chrome 26 / Win7. document.head || document.head = document.getElementsByTagName('head')[0]; Uncaught ReferenceError: Invalid left-hand side in assignment
Патрік

2
Це працює у всіх підтримуваних на даний момент браузерах (IE 11, Edge, FF та Chrome), які не вдається протестувати на сафарі
Aaron

46

Якщо у вас є такий фрагмент HTML:

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

Ви можете змінити фавікон за допомогою Javascript, змінивши, наприклад, елемент HREF на цьому посиланні (якщо припустимо, що ви використовуєте JQuery):

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

Ви також можете створити елемент Canvas і встановити HREF як ToDataURL () полотна, як і Favicon Defender .


1
Думаю, до моменту запуску JS браузер уже побачив посилання і спробував завантажити favicon.png. Це може знадобитися зробити на стороні сервера.
cHao

Якщо ви не використовуєте JQuery, ви можете змінити hrefатрибут #faviconвикористання, document.getElementById('favicon').setAttribute('href','favicon2.png') можливо, ви можете додати його до своєї публікації @fserb?
johannchopin

37

Версія jQuery:

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

а ще краще:

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

Ванільна версія JS:

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

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

@pkExec Комбінація цього та відповіді кепаро вище (обрана відповідь) дала мені змогу працювати як у ff, так і в chrome.
MrShmee

17

Більш сучасний підхід:

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

Потім ви можете використовувати його так:

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

11

Фавікон оголошується в тезі заголовка таким чином:

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

Ви повинні мати можливість просто передати назву потрібної піктограми у дані перегляду та перекинути її в тег заголовка.


1
IIRC, однак, деякі веб-переглядачі (я дивлюсь у ваш бік, IE) часом не дуже поважають це.
Метью Шінккель

(Я виявив, що я маю кращі результати, просто розмістивши файл значка в потрібному місці, а не явне посилання).
Метью Шинкель

9

Ось деякий код, який я використовую, щоб додати динамічну підтримку Favicon до Opera, Firefox та Chrome. Я не міг змусити IE чи Safari працювати. В основному Chrome дозволяє динамічні бажання, але він оновлює їх лише тоді, коли розташування сторінки (або iframeінше в ній) змінюється, наскільки я можу сказати:

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

Щоб змінити фаворити, просто перейдіть favicon.change("ICON URL")до вищевказаного.

(кредити http://softwareas.com/dynamic-favicons за код, на якому я ґрунтувався на цьому.)


Помилка Chrome була виправлена в Chrome 6 (випущений Вересня 10), так що зламати Chrome не дійсно потрібно більше - насправді, я настійно рекомендую не використовувати його , так як він ламає кнопку вперед.
josh3736

У Chrome все ще є та сама помилка, хоча і в дещо інших випадках, ніж конкретна помилка. code.google.com/p/chromium/isissue/detail?id=99549
danorton

4

Я б застосував підхід Грега і зробив спеціальний обробник для favicon.ico Ось (спрощений) обробник, який працює:

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

Тоді ви можете використовувати цей обробник у розділі httpHandlers веб-конфігурації в IIS6 або використовувати функцію "Отоплення обробника" в IIS7.


1
Мені справді цікаво, чому це було знято? це насправді найкраща відповідь, враховуючи, що інші покладаються на сценарії, які можуть бути, а можуть і не бути.
ефірне

1
@ethermal Тому що схоже, що це динамічно на стороні сервера. ОП просила динамізму на стороні клієнта.
Alexis Wilke

3

Єдиний спосіб зробити цю роботу для IE - це налаштувати веб-сервер на обробку запитів * .ico для виклику скриптової мови на вашому сервері (PHP, .NET тощо). Крім того, встановіть * .ico для переадресації на один сценарій, і цей скрипт доставить правильний файл favicon. Я впевнений, що з кешем все ще виникатимуть цікаві проблеми, якщо ви хочете мати можливість відскакувати назад і назад в одному веб-переглядачі між різними фаворитами.


3

Є рішення в одній лінії для тих, хто використовує jQuery:

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

3

Або якщо ви хочете смайлик :)

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

Реквізити до https://koddsson.com/posts/emoji-favicon/


2

За даними WikiPedia , ви можете вказати, який файл favicon завантажити, використовуючи linkтег у headрозділі, з параметром rel="icon".

Наприклад:

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

Я думаю, якби ви хотіли написати якийсь динамічний контент для цього дзвінка, ви мали б доступ до файлів cookie, щоб ви могли таким чином отримати інформацію про свою сесію та представити відповідний вміст.

Ви можете помилитися з форматами файлів (IE, як повідомляється, підтримує лише формат .ICO, тоді як більшість інших підтримує зображення PNG та GIF) і, можливо, проблеми з кешуванням, як у браузері, так і через проксі. Це відбудеться через оригінальну курсиву фавікону, зокрема, для позначення закладки міні-логотипом сайту.


набагато більше, ніж це. stackoverflow.com/a/45301651/661584 файли / інформація на веб-сайті генератора вас здивують - цього питання є багато.
MemeDeveloper

3
Павутина сильно змінюється за 9 років.
staticsan

2

Так цілком можливо

  • Використовуйте рядок запитів після favicon.ico (та інших посилань на файли - див. Посилання відповідей нижче)
  • Просто переконайтеся, що сервер відповідає на "someUserId" правильним файлом зображення (це можуть бути статичні правила маршрутизації або динамічний код на стороні сервера).

напр

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

Тоді незалежно від мови / рамки сервера, якою ви користуєтесь, легко можна знайти файл на основі userId і подати його у відповідь на цей запит .

Але, як правильно робити фавікони (це насправді дуже складна тема ), будь ласка, дивіться відповідь тут https://stackoverflow.com/a/45301651/661584

Набагато простіше, ніж опрацювати всі деталі самостійно.

Насолоджуйтесь.


Так, посилання хороша. Я думаю, що головна причина, чому ці відповіді не працюють в IE, полягає в тому, що вони не використовують цю піктограму за замовчуванням <link>, а натомість шукають apple-touch-iconабо інший подібний варіант.
Алексіс Вілке

1

Я використовую favico.js у своїх проектах.

Це дозволяє змінювати фавікон на ряд попередньо визначених форм, а також на замовлення.

Внутрішньо він використовується canvasдля візуалізації та base64URL-адреси даних для кодування значків.

Бібліотека також має приємні функції: значки та анімації значків; нібито ви навіть можете передати відео з веб-камери в значок :)


Посилання та бібліотека дуже корисні. Надайте опис, як це працює, щоб це також стало вагомою відповіддю на вказане питання.
Діма Тиснек

1
Дякую @DimaTisnek. Я оновив свою відповідь.
Оскар Неварес

0

Я використовую цю функцію постійно під час розробки сайтів ... тож я можу побачити, на якій вкладці працює локальний, розробник чи продавець.

Тепер, коли Chrome підтримує файли SVG, це робить його набагато простіше.

Сценарій Тампермонкі

Попросіть представника на веб-сторінці https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360f для скрипта тампермонеї, який вказує на демонстраційний сайт, на який я зафіксував https://elliz.github.io/svg-favicon/

Основний код

Адаптовано це з іншої відповіді ... можна було б покращити, але досить добре для моїх потреб.

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

})();

Просто вставте свій власний SVG (можливо, очищений SVGOMG Джейка Арчібальда, якщо ви використовуєте інструмент) в const вгорі. Переконайтеся, що він квадратний (за допомогою атрибута viewBox), і вам добре піти.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.