本文灵感来源于 Chrome 插件——Favicon Changer。
Favicon Changer 可以让你更改书签、单个网页和整个网站的 favicon。
Favicon Changer 的原理
Favicon Changer 插件通过修改网页的 DOM 结构来实现更改Favicon 图标。在插件启用时:
- 它会检测网页的
<head>标签中是否存在 Favicon 图标的链接。 - 如果存在将其替换为插件中配置的新链接。
- 如果网页中没有 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 的安全多了,不仅精确匹配了 icon 和 shortcut 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');