【JS 小知识】 添加删除网站的 Favicon

870 阅读2分钟

JS 小知识】 添加删除网站的 Favicon

本文灵感来源于 Chrome 插件——Favicon Changer

Favicon Changer 可以让你更改书签、单个网页和整个网站的 favicon。

Favicon Changer 的原理

Favicon Changer 插件通过修改网页的 DOM 结构来实现更改Favicon 图标。在插件启用时:

  1. 它会检测网页的 <head> 标签中是否存在 Favicon 图标的链接。
  2. 如果存在将其替换为插件中配置的新链接。
  3. 如果网页中没有 Favicon 图标的链接,则插件会在 <head> 标签中添加一个新的 <link> 元素来引用新的 Favicon 图标。
graph TD;
A[插件启用] --> B[checkFavicon 检测是否存在 Favicon 图标链接];
B -- 存在 --> C[setFavicon 替换为新链接];
B -- 不存在 --> D[createFavicon & setFavicon  创建新的链接并添加];

checkFavicon

检测网页的 <head> 标签中是否存在 Favicon 图标的链接。

CSS 方法

const existingFavicon = document.querySelector("link[rel*='icon']");

这里使用了属性选择器 link[rel*='icon'],其中的星号(*)表示“包含”的意思。这意味着选择器会匹配所有包含 "icon" 字符串的 rel 属性,不论其前面还是后面是否有其他字符串。

为什么不使用精确匹配的属性选择器 link[rel='icon'] 呢?

这里因为 favicon 有两种书写方式:

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

精确匹配则可能会错过一些 Favicon 链接,导致插件无法正确工作 ,而 link[rel*='icon'] 会匹配到这两个链接元素,因为它们的 rel 属性都包含 "icon" 字符串。

JS 方法

这个方法就比 CSS 的安全多了,不仅精确匹配了 iconshortcut icon,还使用了 toLowerCase 避免大小写的问题。

// 获取页面上的 link 元素
const linkElements = document.getElementsByTagName('link');

// 定义变量标记 favicon 是否存在
let faviconExists = false;

// 遍历 link 元素,检查它们的 rel 属性是否包含 "icon" 或 "shortcut icon"
for (let i = 0; i < linkElements.length; i++) {
  const link = linkElements[i];
  if (link.rel.toLowerCase() === 'icon' || link.rel.toLowerCase() === 'shortcut icon' ) {
    faviconExists = true;
    break;
  }
}

// 输出结果
if (faviconExists) {
  console.log('Favicon exists.');
} else {
  console.log('Favicon does not exist.');
}

最后,我们把 JS 代码放进 checkFavicon 函数,第一步就完成了。

createFavicon

如果网页中没有 Favicon 图标的链接,则插件会在 <head> 标签中添加一个新的 <link> 元素来引用新的 Favicon 图标。

function createFavicon() { 
    // 如果网页中没有Favicon链接,则添加一个新的<link>元素
    const newFavicon = document.createElement('link');
    newFavicon.type = 'image/x-icon';
    newFavicon.rel = 'shortcut icon';
    document.getElementsByTagName('head')[0].appendChild(newFavicon);
    return newFavicon;
}

setFavicon

function setFavicon(newFaviconUrl) {
    let existingFavicon =checkFavicon();
    if (!existingFavicon) {
        existingFavicon = createFavicon();
    }
    // 替换Favicon链接
    existingFavicon.href = newFaviconUrl;
}

// 示例:更改百度网站的Favicon图标
setFavicon('https://www.baidu.com/favicon.ico');