切换FontAwesome图标时<title>元素丢失,如何更新标题?
解决FontAwesome切换图标时元素丢失的问题 <a class="header-anchor" href="#解决fontawesome切换图标时元素丢失的问题" aria-hidden="true">#</a></h1>
<p>通过CDN引入FontAwesome后,初始带<code>title</code>属性的<code><i></code>元素会被自动转换为嵌套<code><title></code>的<code><svg></code>。但修改<code><svg></code>的FontAwesome类切换图标时,内部的<code><title></code>元素会被移除,无法正常更新图标标题。</p>
<h2 id="方案一:切换类后手动重建元素">方案一:切换类后手动重建<title>元素 <a class="header-anchor" href="#方案一:切换类后手动重建元素" aria-hidden="true">#</a></h2>
<p>FontAwesome修改类时会重新生成整个SVG节点,因此需要在渲染完成后手动添加并配置<code><title></code>元素:</p>
<pre class="hljs"><code class="language-javascript volc-pre-code">$(document).on('click', '#switchIconBtn', async (ev) => {
const iconEl = document.querySelector('#commentIcon');
let newTitleText;
// 切换图标类
if(iconEl.classList.contains('fa-comment-dots')) {
iconEl.classList.remove('fa-comment-dots');
iconEl.classList.add('fa-comment-medical');
newTitleText = 'add a comment';
} else {
iconEl.classList.remove('fa-comment-medical');
iconEl.classList.add('fa-comment-dots');
newTitleText = 'edit comment';
}
// 等待FontAwesome完成SVG重渲染
setTimeout(() => {
let titleEl = iconEl.querySelector('title');
let titleId = iconEl.getAttribute('aria-labelledby');
// 若不存在title元素则创建
if (!titleEl) {
titleId = titleId || `icon-title-${Date.now()}`;
// SVG元素需用命名空间创建
titleEl = document.createElementNS('http://www.w3.org/2000/svg', 'title');
titleEl.id = titleId;
iconEl.insertBefore(titleEl, iconEl.firstChild);
iconEl.setAttribute('aria-labelledby', titleId);
}
// 更新标题文本
titleEl.textContent = newTitleText;
// 更新HTML预览
getIconOuterHTML().then(output => {
document.querySelector('#htmlRepresentation').innerHTML = output;
});
}, 100);
});
</code></pre>
<h2 id="方案二:重新创建元素(更推荐)">方案二:重新创建<i>元素(更推荐) <a class="header-anchor" href="#方案二:重新创建元素(更推荐)" aria-hidden="true">#</a></h2>
<p>直接替换当前的SVG元素为新的<code><i></code>标签,让FontAwesome自动完成转换,无需手动处理SVG内部结构:</p>
<pre class="hljs"><code class="language-javascript volc-pre-code">$(document).on('click', '#switchIconBtn', async (ev) => {
const iconEl = document.querySelector('#commentIcon');
const parent = iconEl.parentNode;
let newClass, newTitleText;
// 确定新的图标类和标题文本
if(iconEl.classList.contains('fa-comment-dots')) {
newClass = 'fas fa-comment-medical';
newTitleText = 'add a comment';
} else {
newClass = 'fas fa-comment-dots';
newTitleText = 'edit comment';
}
// 创建新的<i>元素
const newIcon = document.createElement('i');
newIcon.id = 'commentIcon';
newIcon.className = newClass;
newIcon.setAttribute('title', newTitleText);
// 替换旧元素
parent.replaceChild(newIcon, iconEl);
// 等待渲染后更新预览
getIconOuterHTML().then(output => {
document.querySelector('#htmlRepresentation').innerHTML = output;
});
});
</code></pre>
<h3 id="方案优势说明">方案优势说明 <a class="header-anchor" href="#方案优势说明" aria-hidden="true">#</a></h3>
<p>方案二更可靠,它完全利用FontAwesome的原生转换逻辑,避免手动操作SVG内部节点可能带来的兼容性问题(比如FontAwesome版本更新后内部结构变化)。</p>
<p>内容的提问来源于stack exchange,提问作者JohnRDOrazio</p>
相关产品推荐
相关产品推荐

