标签带有空格无效

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。

→转载请注明出处←