写在前面:
前段时间,我将个人网站的建站工具更换为了Halo,在使用中也遇到一些问题,也不算问题吧,新的工具使用起来总会有些自定义的需求产生,比如本文要记录的这个,权当是一个小小的经验分享吧。
我使用的主题是halo-theme-joe3.0,当我在增添网站的菜单栏时,发现主题预设的图标显得有些单一,缺少一些独特风格和个性。尽管之前已利用主题的自定义选项为菜单添加了图标,但新加入的项目却依然沿用了默认样式。鉴于此次新增的菜单项数量较多,若逐一调整图标显然耗时费力,因此,我开始思考是否有可能对这些默认图标进行统一的优化与替换,于是就有了以下解决方案。
解决方案:
为了实现这一目标,可以通过Halo管理后台系统设置
自带的代码注入功能,在 全局<head>标签
中嵌入一段定制的脚本,从而将所有带有class="m-icon jiewen joe-icon-zuzhijiagou"
的图标替换为个性化的图标。在这之前,先在iconfont平台上创建自己的图标,并生成在线链接代码以供我们引用;比如我的图标链接是//at.alicdn.com/t/c/font_4691632_xtzkb3s398.css
,文件中Font Family
为Marvel
。
代码逻辑设计上,最初考虑采用随机图标,以减少重复出现的概率(实际中失败了,相邻的图标也出现了重复),最终我决定按照顺序逐个替换图标(用完再循环),以此最大可能确保每个图标的独特性及其正确加载。以下是实现此功能的完整代码:
<!-- 引入字体文件的 CSS 链接 -->
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4691632_xtzkb3s398.css">
<!-- class="m-icon jiewen joe-icon-zuzhijiagou" 的图标替换为Marvel的图标 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
var icons = document.querySelectorAll('.m-icon.jiewen');
var marvelIcons = [
'hero-lvdengxia', 'hero-leishen', 'hero-lvjuren', 'hero-leisheyan',
'hero-meiguoduichang', 'hero-shandianxia', 'hero-sishi',
'hero-shenqixiansheng', 'hero-huoxinglieren', 'hero-qianshuixia',
'hero-yuanzixia', 'hero-jinganglang', 'hero-bianfuxia', 'hero-chaoren',
'hero-zhizhuxia', 'hero-hongxuanfeng', 'hero-heifuwang',
'hero-gangtiexia', 'hero-yingguoduichang', 'hero-yiren'
];
icons.forEach(function(iconElement, index) {
// 移除旧的类
iconElement.className = '';
// 获取当前索引对应的图标名称
var newIcon = marvelIcons[index % marvelIcons.length];
// 添加新的类
iconElement.classList.add('m-icon', 'Marvel', newIcon);
});
});
</script>
代码解释:
-
引入字体文件:首先通过
<link>
标签引入字体文件//at.alicdn.com/t/c/font_4691632_xtzkb3s398.css
,确保页面加载时能够访问到这些图标。 -
JavaScript 逻辑:
- 监听
DOMContentLoaded
事件,确保 DOM 加载完成后再执行脚本。 - 使用
querySelectorAll
查找所有具有.m-icon.jiewen
类名的元素。 - 遍历找到的每个图标元素,并清除其原有的类名。
- 按照顺序选取一个新的图标名称,并将其添加到元素的类名中。
- 使用
%
运算符确保即使图标数量不足,也能循环使用这些图标。
- 监听
呈现结果:
最终,每个 .m-icon.jiewen
元素会被替换为 class="m-icon Marvel hero-{icon_name}"
形式的类名,并且这些图标将按照顺序依次分配,直到所有需要替换的图标都被处理完毕。
附在最后
随机图标代码:
在这里也附上随机图标实现的代码,图标的重复性不确定,值得一提的是,每次页面刷新图标都会变更,而前面的按序图标是固定的,若是想要随机变化的效果也是可以的。或者有能力可以再优化后使用:
<!-- 在<head>中加入以下代码 -->
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4691632_xtzkb3s398.css">
<script>
document.addEventListener('DOMContentLoaded', function() {
var icons = document.querySelectorAll('.m-icon.jiewen');
var marvelIcons = [
'hero-lvdengxia', 'hero-leishen', 'hero-lvjuren', 'hero-leisheyan',
'hero-meiguoduichang', 'hero-shandianxia', 'hero-sishi',
'hero-shenqixiansheng', 'hero-huoxinglieren', 'hero-qianshuixia',
'hero-yuanzixia', 'hero-jinganglang', 'hero-bianfuxia', 'hero-chaoren',
'hero-zhizhuxia', 'hero-hongxuanfeng', 'hero-heifuwang',
'hero-gangtiexia', 'hero-yingguoduichang', 'hero-yiren'
];
// 随机选择一个图标
function getRandomIcon() {
return marvelIcons[Math.floor(Math.random() * marvelIcons.length)];
}
icons.forEach(function(iconElement) {
// 移除旧的类
iconElement.className = '';
// 避免重复使用图标
var usedIcons = [];
var newIcon;
do {
newIcon = getRandomIcon();
} while (usedIcons.includes(newIcon));
usedIcons.push(newIcon);
// 添加新的类
iconElement.classList.add('m-icon', 'Marvel', newIcon);
});
});
</script>