การเปลี่ยนเว็บไซต์ favicon แบบไดนามิก


347

ฉันมีเว็บแอปพลิเคชันที่มีตราสินค้าตามผู้ใช้ที่ลงชื่อเข้าใช้ในปัจจุบันฉันต้องการเปลี่ยน favicon ของหน้าเป็นโลโก้ของป้ายกำกับส่วนตัว แต่ฉันไม่สามารถหารหัสหรือตัวอย่างใด ๆ เพื่อทำสิ่งนี้. มีใครเคยทำสิ่งนี้มาก่อนหรือไม่

ฉันนึกภาพว่ามีไอคอนโหลในโฟลเดอร์และการอ้างอิงถึงไฟล์ favicon.ico ที่จะใช้ถูกสร้างขึ้นแบบไดนามิกพร้อมกับหน้า HTML คิด?



โปรดทราบว่าการใช้งาน favicon แบบไดนามิกของ Chrome นั้นมีความผิดพลาดและใช้ CPU มากเกินไป ดูcode.google.com/p/chromium/issues/detail?id=121333
brillout

6
ลิงค์ของเกมอาร์เคดเปลี่ยนไป นี่คือสิ่งที่ถูกต้อง
Basil

ดูstackoverflow.com/questions/6296574/…เกี่ยวกับวิธีอัปเดต favicon แบบไดนามิกโดยการวาดที่ด้านบนของภาพเทมเพลตด้วยแคนวาส
จัดการ

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 ที่ไม่ถูกต้อง!
งัด Bynens

8
คุณสามารถค้นหาลิงก์ favicon ที่มีอยู่แล้วและอัปเดตหรือแทนที่ได้อย่างง่ายดาย
keparo

5
Google สามารถให้ favicon ของไซต์คุณได้โดยใช้ url นี้แทนที่ stackoverflow.com ด้วยโดเมนที่คุณต้องการ: s2.googleusercontent.com/s2/favicons?domain=stackoverflow.com
kirb

5
ควรป้อนสิ่งนี้ในคอนโซล Javascript ใน Chrome หรือไม่ ฉันไม่สามารถเปลี่ยน favicons ในเว็บไซต์ต่าง ๆ ได้
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
danorton

การสาธิตไม่ทำงานสำหรับฉันด้วย Chrome 21 / WinXP
Hugo

การสาธิตไม่ทำงานสำหรับฉันใน Chrome 26 / Win7 document.head || document.head = document.getElementsByTagName('head')[0]; Uncaught ReferenceError: Invalid left-hand side in assignment
Patrick

2
วิธีนี้ใช้ได้กับเบราว์เซอร์ที่รองรับในปัจจุบันทั้งหมด (IE 11, Edge, FF และ Chrome) ไม่สามารถทดสอบกับ Safari ได้
Aaron

46

หากคุณมีตัวอย่าง HTML ต่อไปนี้:

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

คุณสามารถเปลี่ยน favicon โดยใช้ 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 การรวมกันของคำตอบนี้และ keparo ข้างต้น (คำตอบที่เลือก) ทำให้มันทำงานได้ทั้ง 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

favicon ถูกประกาศในแท็กหัวด้วยสิ่งที่ชอบ:

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

คุณควรจะสามารถส่งชื่อของไอคอนที่คุณต้องการในข้อมูลมุมมองและโยนมันลงในแท็กส่วนหัว


1
IIRC อย่างไรก็ตามเบราว์เซอร์บางตัว (ฉันกำลังมองหาทิศทางของคุณ IE) บางครั้งก็ไม่เคารพสิ่งนี้
Matthew Schinckel

(ฉันพบว่าฉันมีผลลัพธ์ที่ดีกว่าเพียงแค่มีไฟล์ไอคอนในตำแหน่งที่ถูกต้องมากกว่าลิงก์ที่ชัดเจน)
Matthew Schinckel

9

นี่คือรหัสที่ฉันใช้เพื่อเพิ่มการสนับสนุน favicon แบบไดนามิกให้กับ Opera, Firefox และ Chrome ฉันไม่สามารถทำงาน IE หรือ Safari ได้ โดยทั่วไป Chrome อนุญาตให้ใช้ favicons แบบไดนามิก แต่จะอัปเดตเฉพาะเมื่อการเปลี่ยนแปลงตำแหน่งของหน้า (หรือ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]}

หากต้องการเปลี่ยน favicons เพียงไปfavicon.change("ICON URL")ใช้ข้างต้น

(เครดิตไปที่http://softwareas.com/dynamic-faviconsสำหรับรหัสที่ฉันอ้างอิงตามนี้)


ข้อผิดพลาด Chromeได้รับการแก้ไขใน Chrome 6 (ปล่อยตัว 10 กันยายน) ดังนั้นสับ Chrome ไม่จำเป็นจริงๆอีกต่อไป - ในความเป็นจริงผมขอแนะนำไม่ได้ใช้มันเพราะมันแบ่งปุ่มไปข้างหน้า
josh3736

Chrome ยังคงมีข้อผิดพลาดเดียวกันนั้นแม้ว่าจะอยู่ในสถานการณ์ที่แตกต่างกันเล็กน้อยกว่าข้อผิดพลาดที่ระบุไว้ code.google.com/p/chromium/issues/detail?id=99549
danorton

4

ฉันจะใช้วิธีการของ Greg และสร้างตัวจัดการแบบกำหนดเองสำหรับ 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
ฉันอยากรู้จริงๆว่าทำไมสิ่งนี้ถึงถูกลงคะแนน? นี่เป็นคำตอบที่ดีที่สุดในการพิจารณาคนอื่น ๆ พึ่งพาการเขียนสคริปต์ซึ่งอาจจะมีหรือไม่มีก็ได้
ethermal

1
@ethermal เพราะดูเหมือนว่ามันจะมีพลวัตทางฝั่งเซิร์ฟเวอร์ OP กำลังขอพลวัตทางฝั่งลูกค้า
Alexis Wilke

3

วิธีเดียวที่จะทำให้การทำงานนี้สำหรับ IE คือการตั้งค่าเว็บเซิร์ฟเวอร์ให้คุณดำเนินการกับคำร้องขอ * .ico เพื่อโทรหาภาษาสคริปต์ฝั่งเซิร์ฟเวอร์ของคุณ (PHP, .NET, ฯลฯ ) ตั้งค่า * .ico เพื่อเปลี่ยนเส้นทางไปยังสคริปต์เดียวและให้สคริปต์นี้ส่งไฟล์ favicon ที่ถูกต้อง ฉันแน่ใจว่ายังคงมีปัญหาที่น่าสนใจเกี่ยวกับแคชหากคุณต้องการที่จะสามารถตีกลับไปมาในเบราว์เซอร์เดียวกันระหว่าง favicons ที่แตกต่างกัน


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

ตามที่วิกิพีเดีย , คุณสามารถระบุไฟล์ favicon โหลดโดยใช้linkแท็กในส่วนที่มีพารามิเตอร์ของheadrel="icon"

ตัวอย่างเช่น:

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

ฉันคิดว่าถ้าคุณต้องการเขียนเนื้อหาแบบไดนามิกสำหรับการโทรนั้นคุณจะสามารถเข้าถึงคุกกี้เพื่อให้คุณสามารถดึงข้อมูลเซสชันของคุณด้วยวิธีนั้นและนำเสนอเนื้อหาที่เหมาะสม

คุณอาจเสียรูปแบบไฟล์ได้ (รายงานว่า IE รองรับเฉพาะรูปแบบ. ICO เท่านั้นในขณะที่ทุกคนส่วนใหญ่รองรับภาพ PNG และ GIF) และอาจมีปัญหาการแคชทั้งในเบราว์เซอร์และผ่านทางพร็อกซี่ สิ่งนี้อาจเป็นเพราะความชอบดั้งเดิมของ favicon โดยเฉพาะสำหรับการทำเครื่องหมายที่คั่นหน้าด้วยโลโก้ขนาดเล็กของไซต์


มากไปกว่านั้น stackoverflow.com/a/45301651/661584คำถามที่พบบ่อย / ข้อมูลในเว็บไซต์ของเครื่องกำเนิดไฟฟ้าจะทำให้คุณประหลาดใจ - มีเรื่องราวมากมายในเรื่องนี้
MemeDeveloper

3
เว็บเปลี่ยนไปมากใน 9 ปี
Staticsan

2

ใช่เป็นไปได้โดยสิ้นเชิง

  • ใช้การสอบถามหลัง favicon.ico (และลิงค์ไฟล์อื่น ๆ - ดูลิงค์คำตอบด้านล่าง)
  • ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ตอบสนอง "someUserId" ด้วยไฟล์รูปภาพที่ถูกต้อง (ซึ่งอาจเป็นกฎการกำหนดเส้นทางแบบคงที่หรือ รหัสด้านเซิร์ฟเวอร์แบบไดนามิก )

เช่น

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

ดังนั้นภาษา / กรอบงานของเซิร์ฟเวอร์ใดก็ตามที่คุณใช้ควรจะสามารถค้นหาไฟล์ตาม userIdและให้บริการตามคำขอนั้นนั้น

แต่การทำ favicons ให้ถูกต้อง (เป็นเรื่องที่ซับซ้อนจริงๆ ) โปรดดูคำตอบที่นี่https://stackoverflow.com/a/45301651/661584

ง่ายกว่าการลงรายละเอียดทั้งหมดด้วยตัวเอง

สนุก.


ใช่ลิงค์เป็นสิ่งที่ดี ฉันคิดว่าเหตุผลหลักที่ทำไมคำตอบเหล่านี้ใช้ไม่ได้ใน IE ก็เพราะพวกเขาไม่ได้ใช้ไอคอนเริ่มต้น<link>นั้น แต่ให้มองหาapple-touch-iconตัวแปรอื่น ๆ
Alexis Wilke

1

ฉันใช้favico.jsในโครงการของฉัน

อนุญาตให้เปลี่ยน favicon เป็นรูปร่างที่กำหนดไว้ล่วงหน้าและรูปร่างที่กำหนดเอง

ภายในจะใช้canvasสำหรับการแสดงผลและbase64URL ข้อมูลสำหรับการเข้ารหัสไอคอน

ห้องสมุดยังมีคุณสมบัติที่ดี: ไอคอนตราและภาพเคลื่อนไหว; คุณสามารถสตรีมวิดีโอเว็บแคมลงในไอคอนได้ :)


ลิงค์และห้องสมุดมีประโยชน์มากโปรดให้คำอธิบายวิธีการใช้งานเพื่อให้เป็นคำตอบที่ถูกต้องสำหรับคำถามตามที่ระบุไว้
Dima Tisnek

1
ขอบคุณ @DimaTisnek ฉันอัปเดตคำตอบของฉันแล้ว
Oscar Nevarez

0

ฉันใช้คุณลักษณะนี้ตลอดเวลาเมื่อมีการพัฒนาเว็บไซต์ ... ดังนั้นฉันจึงสามารถดูได้ทันทีว่าแท็บใดที่มีการทำงานในท้องถิ่น dev หรือแยงทำงานอยู่

ตอนนี้ Chrome สนับสนุน SVV favicons แล้วทำให้ง่ายขึ้นมาก

สคริปต์ Tampermonkey

ไปที่https://gist.github.com/elliz/bb7661d8ed1535c93d03afcd0609360fเพื่อดูสคริปต์ tampermonkey ที่ชี้ไปยังไซต์ตัวอย่างที่ฉันไปดู 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 ของ Jake Archibald หากคุณใช้เครื่องมือ) ลงไปที่กลุ่มที่ด้านบน ตรวจสอบให้แน่ใจว่าเป็นรูปสี่เหลี่ยม (ใช้แอตทริบิวต์ viewBox) และคุณก็พร้อมใช้งาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.