标签带有空格无效
document.addEventListener('DOMContentLoaded', function() {
const tagButtons = document.querySelectorAll('button.Label');
tagButtons.forEach(button => {
button.addEventListener('click', function() {
// 先恢复所有标签的 padding
tagButtons.forEach(btn => {
btn.style.padding = '4px';
});
// 再移除当前点击标签的 padding
this.style.padding = '0';
});
});
});
空格无效版带调试信息
包含f12控制台调试信息输出,因为我发现标签有空格的会没有效果,和上面的差不多,多了调试脚本,未到匹配的…
// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
console.log('脚本已加载');
// 保存原始函数
if (window.updateShowTag) {
const originalUpdateShowTag = window.updateShowTag;
// 重写函数
window.updateShowTag = function(tag) {
console.log('updateShowTag 被调用,参数:', tag);
// 先执行原来的逻辑
originalUpdateShowTag(tag);
// 选择所有标签按钮
const tagButtons = document.querySelectorAll('button.Label');
console.log('找到的标签数量:', tagButtons.length);
// 恢复所有标签的 padding
tagButtons.forEach(btn => {
btn.style.padding = '4px';
console.log('恢复 padding: ', btn.textContent.trim());
});
// 找到当前点击的标签
const activeTag = Array.from(tagButtons).find(btn => {
const btnText = btn.textContent.trim().split(/\s+/)[0];
return btnText === tag;
});
if (activeTag) {
activeTag.style.padding = '0';
console.log('设置 padding: 0 给:', activeTag.textContent.trim());
} else {
console.log('未找到匹配的标签:', tag);
}
}
// 页面加载时,根据 URL hash 自动激活对应标签
const currentHash = window.location.hash.substring(1);
if (currentHash) {
console.log('检测到 hash:', currentHash);
window.updateShowTag(currentHash);
}
} else {
console.error('未找到 updateShowTag 函数!');
}
});
全部有效版,空格也有效
这个版本所有页面监听点击事件,就是说你从别的页面点击过来也是有效果的,但是我感觉会不会浪费性能…
(function() {
'use strict';
setTimeout(function() {
const tagButtons = document.querySelectorAll('button.Label');
if (tagButtons.length === 0) return;
tagButtons.forEach(button => {
button.addEventListener('click', function() {
tagButtons.forEach(btn => {
btn.style.setProperty('padding', '4px', 'important');
});
this.style.setProperty('padding', '0', 'important');
});
});
const currentHash = decodeURIComponent(window.location.hash.substring(1));
if (currentHash) {
const activeTag = Array.from(tagButtons).find(btn =>
btn.textContent.trim().includes(currentHash.trim())
);
if (activeTag) {
activeTag.style.setProperty('padding', '0', 'important');
}
}
}, 1000);
})();
全部有效包含调试脚本版
// 调试版:带详细日志,用于定位问题
(function() {
'use strict';
// 延迟执行,确保 DOM 加载完成
setTimeout(function() {
console.log('=== 标签选中调试脚本开始 ===');
// 1. 查找所有标签按钮
const tagButtons = document.querySelectorAll('button.Label');
console.log('找到的标签按钮数量:', tagButtons.length);
if (tagButtons.length === 0) {
console.error('未找到任何 button.Label 元素!');
console.log('页面中所有 button 元素:', document.querySelectorAll('button'));
return;
}
// 2. 为每个按钮绑定点击事件
tagButtons.forEach((button, index) => {
button.addEventListener('click', function() {
console.log(`按钮 #${index} 被点击:`, this.textContent.trim());
// 先恢复所有按钮的 padding
tagButtons.forEach((btn, i) => {
btn.style.setProperty('padding', '4px', 'important');
console.log(`恢复按钮 #${i} 的 padding`);
});
// 再移除当前按钮的 padding
this.style.setProperty('padding', '0', 'important');
console.log(`移除按钮 #${index} 的 padding`);
});
});
// 3. 页面加载时,根据 URL hash 自动激活对应标签
const currentHash = decodeURIComponent(window.location.hash.substring(1));
console.log('当前 URL hash:', currentHash);
if (currentHash) {
const activeTag = Array.from(tagButtons).find((btn, i) => {
const btnText = btn.textContent.trim();
const match = btnText.includes(currentHash.trim());
console.log(`匹配按钮 #${i}: "${btnText}" 包含 "${currentHash}"?`, match);
return match;
});
if (activeTag) {
activeTag.style.setProperty('padding', '0', 'important');
console.log('自动激活标签:', activeTag.textContent.trim());
} else {
console.warn('未找到与 hash 匹配的标签');
}
}
console.log('=== 标签选中调试脚本加载完成 ===');
}, 1000); // 延迟1秒,确保所有DOM都加载好
})();
最终版本仅tag.html页面
这个版本从别的页面点击过来也是有效果的,刷新也是有效果的,具体还有什么BUG的话,麻烦提交评论给我。
(function() {
'use strict';
if (!window.location.pathname.includes('tag.html')) {
return;
}
function handleTagClick(event) {
const button = event.target.closest('button.Label');
if (!button) return;
document.querySelectorAll('button.Label').forEach(btn => {
btn.style.setProperty('padding', '4px', 'important');
});
button.style.setProperty('padding', '0', 'important');
}
const tagContainer = document.getElementById('taglabel');
if (tagContainer) {
tagContainer.addEventListener('click', handleTagClick);
}
function activateTagByHash() {
const currentHash = decodeURIComponent(window.location.hash.substring(1));
if (currentHash) {
document.querySelectorAll('button.Label').forEach(btn => {
btn.style.setProperty('padding', '4px', 'important');
});
const activeTag = Array.from(document.querySelectorAll('button.Label')).find(btn =>
btn.textContent.trim().includes(currentHash.trim())
);
if (activeTag) {
activeTag.style.setProperty('padding', '0', 'important');
}
}
}
setTimeout(activateTagByHash, 1000);
window.addEventListener('hashchange', activateTagByHash);
})();
1.新增 activateTagByHash 函数:专门负责根据当前 URL hash 找到并激活对应标签。
2.监听 hashchange 事件:每次URL 中的hash 发生变化(比如点击标签、前进后退),都会自动调用
activateTagByHash,确保选中状态始终同步。
3.刷新后自动激活:页面刷新
时,setTimeout 会延迟执行一次,保证DOM 加载完成后再根据 hash激活标签。
这样,无论是刷新页面、点击标签,还是使用浏览器的前进后退按钮,选中状态都会一直保持正确,不会再出现失效的情况。
为什么这个版本(最终版)性能更好?
旧方式(之前的)
·给每一个标签按钮都绑一个点击事件
·标签越多,事件越多
·别的页面也可能执行,浪费资源
现在这个最终版
·只绑1次事件,绑在标签父容器上
·不管你以后有10个、50个、100个标签
→都只占用1个事件监听
·这叫事件委托(最优性能写法)
再加你现在的双重保险
·只在 tag.html执行
首页、文章页、别的页面完全不跑这段代
码
监听 hashchange 而不是全局疯狂监听
·无循环、无定时器狂跑、无多余计算
我比较懒,也不像加太多东西,所以效果就是点击那个标签就直接去它的css样式(padding:4px),这样一来背景直接缩小,效果还是蛮明显能区分的…
轮子已经做好了,可以高仿做一个比如,点击标签后那个标签背景颜色就不圆角变成直角,去除:.label{border-radius:2em}的这个样式,然后背景颜色大小统一,已经点击选中的标签是直角的背景颜色…
代码添加到之前引用到头部的自定义js文件里面就好了。
发现小BUG,已修正版
如果用户直接打开这个页面,默认在all全部标签会无效,于是我又改了一下没有实测,因为影响不大的小BUG懒得测试了。
(function() {
'use strict';
if (!window.location.pathname.includes('tag.html')) return;
function handleTagClick(event) {
const button = event.target.closest('button.Label');
if (!button) return;
document.querySelectorAll('button.Label').forEach(btn => {
btn.style.setProperty('padding', '4px', 'important');
});
button.style.setProperty('padding', '0', 'important');
}
const tagContainer = document.getElementById('taglabel');
if (tagContainer) {
tagContainer.addEventListener('click', handleTagClick);
}
function activateTagByHash() {
const currentHash = decodeURIComponent(window.location.hash.substring(1));
const allTags = document.querySelectorAll('button.Label');
allTags.forEach(btn => {
btn.style.setProperty('padding', '4px', 'important');
});
if (!currentHash) {
const allBtn = Array.from(allTags).find(btn =>
btn.textContent.trim().toLowerCase().startsWith('all')
);
if (allBtn) allBtn.style.setProperty('padding', '0', 'important');
return;
}
const activeTag = Array.from(allTags).find(btn =>
btn.textContent.trim().includes(currentHash.trim())
);
if (activeTag) activeTag.style.setProperty('padding', '0', 'important');
}
setTimeout(activateTagByHash, 1000);
window.addEventListener('hashchange', activateTagByHash);
})();
已经实测直接打开tag标签页默认在全部标签all也有效…
加个选中标签呼吸:
加上一个选中的标签会有"呼吸"放大效果,不然感觉选中的标签区分不太明确…
/* 1. 呼吸动画 */
@keyframes tagBreath {
0% {
box-shadow: 0 0 5px rgba(2, 122, 255, 0.2);
transform: scale(1);
}
50% {
box-shadow: 0 0 15px rgba(2, 122, 255, 0.6);
transform: scale(1.1); /* 既然 padding 没了,缩放稍微大一点补偿视觉 */
}
100% {
box-shadow: 0 0 5px rgba(2, 122, 255, 0.2);
transform: scale(1);
}
}
/* 2. 核心:只抓取被 JS 设置了 padding 为 0 的标签 */
/* 适配可能出现的不同写法:padding: 0, padding: 0px, padding:0 */
.Label[style*="padding: 0"],
.Label[style*="padding:0"],
.Label[style*="padding: 0px"] {
animation: tagBreath 2s linear infinite !important;
display: inline-block !important;
position: relative;
z-index: 10;
/* 既然选中了,可以给它一个更亮的主题色,不需要就把下面2行删除或者注释掉不改变颜色 */
background-color: #0075ca !important;
color: white !important;
}
选中标签呼吸写法说明:
“选中"的特征是 padding: 0,那我们的 CSS 选择器就要精准地去抓那个被设为0的标签。
·特征唯一性:普通状态下的 Gmeek 标签都有默认的padding。只有当你点击后,你的 JS才会给那个特定的标签注入 style="padding: 0;"。
·CSS 属性雷达: ,Label[style*="padding: 0"]就像一个雷达,它会扫描页面上所有的标签,一旦发现谁的 style 属性里冒出了 padding: 0(好像也是前面的js弄,久了我忘了,因为那时候我想选中的标签设置为0然后它就会变小就和没有选中的标签有差距凸出它是被选中的,后来我发现好像凸出不太明显,然后再想在它的基础上添加呼吸动起来的效果),就立刻给它套上呼吸动效。
·视觉补偿:因为你把选中标签的 padding 设为了0,标签会变小。我在动画里把 scale 增加到了1.1,这样它呼吸时会向外扩张,弥补了变小后的视觉缺失,显得更有动感。
现在的做法是"JS触发状态,CSS 执行表现”,这是现代前端开发中最推荐的高性能模式。它比单纯用JS撸动画要专业得多。
总之说人话就是我能用css就是css不用js。