Thay đổi linh hoạt trang web


347

Tôi có một ứng dụng web được gắn nhãn hiệu theo người dùng hiện đang đăng nhập. Tôi muốn thay đổi hình đại diện của trang thành logo của nhãn riêng, nhưng tôi không thể tìm thấy bất kỳ mã hoặc bất kỳ ví dụ nào về cách để làm điều này. Có ai đã làm thành công điều này trước đây?

Tôi đang hình dung có một tá biểu tượng trong một thư mục và tham chiếu mà tệp favicon.ico sẽ sử dụng chỉ được tạo động cùng với trang HTML. Suy nghĩ?


40
Có một trò chơi arcade trong một favicon.
Corey Trager

Lưu ý rằng việc triển khai favicon động của Chrome là lỗi và sử dụng quá nhiều CPU. Xem code.google.com/p/chromium/issues/detail?id=121333
sáng chói

6
Liên kết cho trò chơi arcade đã thay đổi. Đây là một trong những chính xác.
Basil

Xem stackoverflow.com/questions/6296574/ trên về cách tự động cập nhật favicon bằng cách vẽ trên đầu của một hình ảnh mẫu bằng vải.
xử lý

1
Lỗi nhỏ trong ví dụ mã được cung cấp trong câu trả lời được chấp nhận. Tôi không có đủ điểm danh tiếng để bình luận về câu trả lời, do đó viết ở đây để thay thế. Dòng cuối cùng có dấu ngoặc đơn được hoán đổi:} ()); nên đọc })(); Thật tuyệt khi ví dụ mã được cập nhật vì rất có thể nó được sao chép và dán bởi những người khác.
Goran W

Câu trả lời:


396

Tại sao không?

(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 thật tuyệt với nó.

chỉnh sửa để ghi đè chính xác các biểu tượng hiện có


2
Tôi nghĩ rằng điều này gần với những gì tôi đang tìm kiếm, nhưng làm thế nào tôi có được HREF thích hợp từ cơ sở dữ liệu. Tôi cho rằng tôi sẽ phải thực hiện tra cứu máy chủ từ javascript, nhưng tôi không muốn nó quá phức tạp. Cảm ơn vì tiền hỗ trợ.
SqlRyan

34
Vì dù sao nó cũng không hoạt động trong IE, nên bạn có thể xóa shortcutkhỏi relthuộc tính. shortcutlà một mối quan hệ liên kết độc quyền IE không hợp lệ!
Mathias Bynens

8
Bạn có thể dễ dàng tìm kiếm một liên kết favicon hiện có và cập nhật nó hoặc thay thế nó.
keparo

5
Google có thể cung cấp cho bạn favicon của một trang web bằng cách sử dụng url này, thay thế stackoverflow.com bằng tên miền bạn muốn: s2.googleusercontent.com/s2/favicons?domain=stackoverflow.com
kirb

5
Có nên nhập cái này trong bảng điều khiển Javascript trong Chrome không? Tôi không thể lấy nó để thay đổi favicon trên các trang web khác nhau theo cách đó.
powerj1984

88

Đây là một số mã hoạt động trong Firefox, Opera và Chrome (không giống như mọi câu trả lời khác được đăng ở đây). Đây là một bản demo mã khác nhau hoạt động trong IE11 . Ví dụ sau có thể không hoạt động trong Safari hoặc 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);
}

Sau đó, bạn sẽ sử dụng nó như sau:

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

Ngã ba hoặc xem một bản demo .


Các lỗi Chrome đã được cố định trong Chrome 6 (phát hành 10 tháng 9), do đó Chrome hack là không thực sự cần thiết nữa - trong thực tế, tôi muốn mạnh mẽ đề nghị không sử dụng nó vì nó phá vỡ nút phía trước.
josh3736

Lỗi Chrome có thể đã được sửa, nhưng nó lại bị hỏng trong 14.0.835.187.
danorton

Bản demo không hoạt động với tôi với Chrome 21 / WinXP.
Hugo

Bản demo không hoạt động với tôi trong Chrome 26 / Win7. document.head || document.head = document.getElementsByTagName('head')[0]; Uncaught ReferenceError: Invalid left-hand side in assignment
Patrick

2
Điều này hoạt động trong tất cả các trình duyệt hiện được hỗ trợ (IE 11, Edge, FF và Chrome) không thể kiểm tra bằng safari
Aaron

46

Nếu bạn có đoạn mã HTML sau:

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

Chẳng hạn, bạn có thể thay đổi favicon bằng Javascript bằng cách thay đổi phần tử HREF trên liên kết này (giả sử bạn đang sử dụng JQuery):

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

Bạn cũng có thể tạo một phần tử Canvas và đặt HREF là ToDataURL () của khung vẽ, giống như Favicon Defender .


1
Tôi nghĩ rằng vào thời điểm JS chạy, trình duyệt sẽ thấy liên kết và đã thử tải favicon.png. Điều này có thể cần phải được thực hiện phía máy chủ.
cHao

Nếu bạn không sử dụng JQuery, bạn có thể thay đổi hrefthuộc tính của #faviconviệc sử dụng document.getElementById('favicon').setAttribute('href','favicon2.png') Có lẽ bạn có thể thêm nó vào bài đăng của mình @fserb?
johannchopin

37

Phiên bản jQuery:

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

hoặc thậm chí tốt hơn:

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

Phiên bản Vanilla JS:

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

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

@pkExec Một sự kết hợp giữa câu trả lời này và câu trả lời của keparo ở trên (câu trả lời được chọn) đã khiến nó hoạt động ở cả ff và chrome đối với tôi.
MrShmee 20/2/2015

17

Một cách tiếp cận hiện đại hơn:

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

Sau đó bạn có thể sử dụng nó như thế này:

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

11

Favicon được khai báo trong thẻ head với nội dung như:

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

Bạn có thể chỉ cần chuyển tên của biểu tượng bạn muốn trong dữ liệu xem và ném nó vào thẻ head.


1
Tuy nhiên, IIRC, một số trình duyệt (tôi đang nhìn theo hướng của bạn, IE) đôi khi không thực sự tôn trọng điều này.
Matthew Schinckel

(Tôi thấy tôi có kết quả tốt hơn khi chỉ có tệp biểu tượng ở đúng vị trí, thay vì liên kết rõ ràng).
Matthew Schinckel

9

Đây là một số mã tôi sử dụng để thêm hỗ trợ favicon động cho Opera, Firefox và Chrome. Tôi không thể làm cho IE hoặc Safari hoạt động được. Về cơ bản Chrome cho phép các favicon động, nhưng nó chỉ cập nhật chúng khi vị trí của trang (hoặc một iframev.v.) thay đổi theo như tôi có thể nói:

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

Để thay đổi favicon, chỉ cần favicon.change("ICON URL")sử dụng ở trên.

(ghi có vào http://softwareas.com/dynamic-favicons cho mã tôi dựa trên mã này.)


Các lỗi Chrome đã được cố định trong Chrome 6 (phát hành 10 tháng 9), do đó Chrome hack là không thực sự cần thiết nữa - trong thực tế, tôi muốn mạnh mẽ đề nghị không sử dụng nó vì nó phá vỡ nút phía trước.
josh3736

Chrome vẫn có cùng một lỗi, mặc dù trong các trường hợp hơi khác so với lỗi cụ thể được ghi nhận. code.google.com/p/chromium/issues/detail?id=99549
danorton

4

Tôi sẽ sử dụng phương pháp của Greg và tạo một trình xử lý tùy chỉnh cho favicon.ico Đây là một trình xử lý (đơn giản hóa) hoạt động:

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

Sau đó, bạn có thể sử dụng trình xử lý đó trong phần httpHandlers của cấu hình web trong IIS6 hoặc sử dụng tính năng 'Handler Mappings' trong IIS7.


1
Tôi thực sự tò mò tại sao điều này đã bị hạ cấp? đây thực sự là câu trả lời tốt nhất khi xem xét tất cả những người khác dựa vào kịch bản có thể có hoặc không có sẵn.
etherody

1
@ethermal Vì có vẻ như nó động ở phía máy chủ. OP đã yêu cầu sự năng động về phía khách hàng.
Alexis Wilke

3

Cách duy nhất để thực hiện công việc này cho IE là đặt máy chủ web của bạn xử lý các yêu cầu cho * .ico để gọi ngôn ngữ kịch bản phía máy chủ của bạn (PHP, .NET, v.v.). Đồng thời thiết lập * .ico để chuyển hướng đến một tập lệnh duy nhất và có tập lệnh này cung cấp tệp favicon chính xác. Tôi chắc chắn vẫn sẽ có một số vấn đề thú vị với bộ đệm nếu bạn muốn có thể bật lại trong cùng một trình duyệt giữa các favicon khác nhau.


3

Có một giải pháp dòng duy nhất cho những người sử dụng jQuery:

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

3

Hoặc nếu bạn muốn một biểu tượng cảm xúc :)

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

Đạo cụ cho https://koddsson.com/posts/emoji-favicon/


2

Dựa theo WikiPedia , bạn có thể chỉ định tệp favicon nào sẽ tải bằng cách sử dụng linkthẻ trong headphần này, với tham số là rel="icon".

Ví dụ:

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

Tôi tưởng tượng nếu bạn muốn viết một số nội dung động cho cuộc gọi đó, bạn sẽ có quyền truy cập vào cookie để bạn có thể truy xuất thông tin phiên của mình theo cách đó và trình bày nội dung phù hợp.

Bạn có thể không thích các định dạng tệp (IE chỉ hỗ trợ định dạng .ICO, trong khi hầu hết mọi người khác đều hỗ trợ hình ảnh PNG và GIF) và có thể các vấn đề về bộ đệm, cả trên trình duyệt và qua proxy. Điều này có thể là do sự chú ý ban đầu của favicon, đặc biệt, để đánh dấu một dấu trang bằng logo nhỏ của trang web.


nhiều hơn thế stackoverflow.com/a/45301651/661584 các faqs / thông tin trên trang web của trình tạo sẽ làm bạn ngạc nhiên - có rất nhiều chủ đề này.
MemeDeveloper

3
Web thay đổi rất nhiều trong 9 năm.
staticsan

2

Vâng hoàn toàn có thể

  • Sử dụng chuỗi truy vấn sau favicon.ico (và các liên kết tệp khác - xem liên kết trả lời bên dưới)
  • Chỉ cần đảm bảo rằng máy chủ phản hồi "someUserId" với tệp hình ảnh chính xác (có thể là quy tắc định tuyến tĩnh hoặc mã phía máy chủ động ).

ví dụ

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

Sau đó, bất kỳ ngôn ngữ / khung công tác phía máy chủ nào bạn sử dụng đều có thể dễ dàng tìm thấy tệp dựa trên userId và phục vụ nó để đáp ứng yêu cầu đó .

Nhưng để thực hiện favicon đúng cách (đây thực sự là một chủ đề rất phức tạp ), vui lòng xem câu trả lời tại đây https://stackoverflow.com/a/45301651/661584

Dễ dàng hơn rất nhiều so với việc tự mình làm ra tất cả các chi tiết.

Thưởng thức.


Vâng, liên kết là tốt. Tôi nghĩ rằng lý do chính tại sao những câu trả lời này không hoạt động trong IE là vì họ không sử dụng biểu tượng mặc định đó <link>, mà thay vào đó, hãy tìm apple-touch-iconhoặc một số biến thể khác như vậy.
Alexis Wilke

1

Tôi sử dụng favico.js trong các dự án của mình.

Nó cho phép thay đổi favicon thành một loạt các hình dạng được xác định trước và cả hình dạng tùy chỉnh.

Trong nội bộ, nó sử dụng canvasđể kết xuất và base64URL dữ liệu để mã hóa biểu tượng.

Thư viện cũng có các tính năng hay: huy hiệu biểu tượng và hình ảnh động; cố ý, bạn thậm chí có thể truyền phát video webcam vào biểu tượng :)


Liên kết và thư viện rất hữu ích, vui lòng cung cấp mô tả cách thức hoạt động để điều này cũng trở thành câu trả lời hợp lệ cho câu hỏi như đã nêu.
Dima Tisnek

1
Cảm ơn @DimaTisnek. Tôi cập nhật câu trả lời của tôi.
Oscar Nevarez

0

Tôi sử dụng tính năng này mọi lúc khi phát triển trang web ... vì vậy tôi có thể thấy trong nháy mắt tab nào có cục bộ, dev hoặc prod chạy trong đó.

Giờ đây, Chrome hỗ trợ favicons SVG, điều đó làm cho nó dễ dàng hơn rất nhiều.

Tập lệnh Tampermonkey

Có một người thích ở https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360f cho một kịch bản tampermonkey trỏ đến một trang web demo mà tôi đã tặc lưỡi https://elliz.github.io/svg-favicon/

Mã cơ bản

Điều chỉnh từ câu trả lời khác ... có thể được cải thiện nhưng đủ tốt cho nhu cầu của tôi.

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

})();

Chỉ cần bật SVG của riêng bạn (có thể được làm sạch bằng SVGOMG của Jake Archibald nếu bạn đang sử dụng một công cụ) vào const ở trên cùng. Hãy chắc chắn rằng nó là hình vuông (sử dụng thuộc tính viewBox) và bạn sẽ ổn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.