You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原生JS实现HTML按钮文本类数据属性切换且保留嵌套SVG图标

问题解决:切换按钮时保留SVG图标同时正常切换文本

问题场景

两个导航按钮:一个是带文本的菜单按钮(可切换"Menu"/"Close"),另一个是仅包含SVG图标的用户菜单按钮。当前点击按钮时,SVG图标会被移除,文本按钮功能正常,需要修改代码确保SVG完整,文本切换不受影响。

问题根源

  • 事件目标错误:点击SVG时,e.target指向的是SVG元素而非按钮本身,导致后续操作错误作用在SVG上。
  • 无差别文本替换:代码对所有按钮执行innerText替换逻辑,SVG按钮没有文本切换的data-text-swap属性,但仍被修改,直接清空了SVG内容。

修改方案

核心修改点

  • 用e.currentTarget替代e.target,确保始终操作绑定事件的按钮元素,而非内部的SVG。
  • 给文本切换逻辑加判断:仅对带有data-text-swap属性的按钮执行文本替换,SVG按钮跳过这部分。
  • 清理其他激活按钮时,同样区分处理:带文本属性的按钮恢复文本,其他仅重置类和aria-expanded属性。

修改后的JS代码

window.addEventListener("DOMContentLoaded", function() {
  const navigation = (() => {
    const buttons = document.querySelectorAll("[data-nav-toggle]");
    const containers = document.querySelectorAll("[data-nav-container]");

    if (!buttons.length) return;

    function menuToggleHandler() {
      buttons.forEach((button) => {
        button.addEventListener("click", toggleContainer);
      });
    }

    function toggleContainer(e) {
      e.stopPropagation();
      // 用currentTarget确保操作的是绑定事件的按钮,而非内部SVG
      toggleButtonAttributes(e.currentTarget);
      toggleContainers(e.currentTarget);
    }

    function toggleButtonAttributes(button) {
      button.classList.toggle("is-active");

      const expandedValue = button.getAttribute("aria-expanded");
      const setValue = expandedValue === "true" ? "false" : "true";
      button.setAttribute("aria-expanded", setValue);

      // 仅对有data-text-swap的按钮执行文本切换
      const hasTextSwap = button.hasAttribute("data-text-swap");
      if (hasTextSwap) {
        const originalValue = button.getAttribute("data-text-original");
        const swapValue = button.getAttribute("data-text-swap");

        if (swapValue.trim() === button.innerText.trim()) {
          button.innerText = originalValue;
        } else {
          button.setAttribute("data-text-original", button.innerText.trim());
          button.innerText = swapValue;
        }
      }

      // 清理其他激活的按钮
      document.querySelectorAll(".is-active").forEach(function(buttonActive) {
        if (buttonActive !== button) {
          buttonActive.classList.remove("is-active");
          buttonActive.setAttribute("aria-expanded", "false");
          // 仅对有文本切换属性的按钮恢复文本
          if (buttonActive.hasAttribute("data-text-swap")) {
            const originalText = buttonActive.getAttribute("data-text-original");
            buttonActive.innerText = originalText;
          }
        }
      });
    }

    function toggleContainers(button) {
      const parent = button
        .closest("nav")
        .querySelector("[data-nav-container]");
      parent.classList.toggle("is-expanded");
      document
        .querySelectorAll(".is-expanded")
        .forEach(function(parentExpanded) {
          if (parentExpanded !== parent) {
            parentExpanded.classList.remove("is-expanded");
          }
        });
    }

    menuToggleHandler();
  })();
});

其他代码保持不变

  • CSS代码无需修改:
button>svg {
  pointer-events: none;
}
  • HTML代码保持原结构即可,SVG按钮无需添加文本相关的data属性。

内容的提问来源于stack exchange,提问作者Mike Hermary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 07:38:17