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

Web扩展内容脚本添加HTML元素异常:按钮短暂显示后消失

问题:Web扩展注入Modrinth页面的按钮短暂显示后消失

我正在开发一款Web扩展,用于实现我的应用与Modrinth网站(地址格式为https://modrinth.com/(mod或resourcepack或shader)/foo)的集成,但在注入新<a>标签时遇到问题——注入的按钮仅短暂出现后就消失了,预期按钮能稳定显示(样式与页面其他iconified-button一致,位置在输入组区域)。

以下是src/onMod.js中的代码:

const main = () => {
  let inputGroup = document.getElementsByClassName("input-group")[0];
  let mcmodpackmanagerbutton = document.createElement("a");

  let slug = "sodium"; // Place holder

  slug = window.location.href.split("/")[4]; // This thing doesn't change

  mcmodpackmanagerbutton.href = "mcmodpackmanager://modrinthopen?id=" + slug;
  mcmodpackmanagerbutton.className = "iconified-button";
  mcmodpackmanagerbutton.innerHTML = "Open with Minecraft Modpack Manager";
  mcmodpackmanagerbutton.setAttribute("rel", "noopener nofollow"); // Other links on modrinth.com use this

  console.log("SLUG: " + slug);

  inputGroup.appendChild(mcmodpackmanagerbutton);
};

main();

原因分析

Modrinth采用动态渲染的前端框架(如React),页面内容会随框架状态更新重新生成。你的代码首次注入按钮成功后,框架重新渲染对应区域时会覆盖原始DOM,导致注入的按钮被清除。

解决方法

1. 用MutationObserver监听DOM变化,自动重注入

通过监听目标容器的DOM变动,在页面重新渲染后再次注入按钮,同时避免重复创建:

const injectButton = () => {
  // 移除已存在的按钮,防止重复注入
  const existingBtn = document.querySelector('a[href^="mcmodpackmanager://modrinthopen"]');
  if (existingBtn) existingBtn.remove();

  const inputGroup = document.getElementsByClassName("input-group")[0];
  if (!inputGroup) return;

  const btn = document.createElement("a");
  const slug = window.location.href.split("/")[4];
  
  btn.href = `mcmodpackmanager://modrinthopen?id=${slug}`;
  btn.className = "iconified-button";
  btn.innerHTML = "Open with Minecraft Modpack Manager";
  btn.setAttribute("rel", "noopener nofollow");

  inputGroup.appendChild(btn);
};

// 首次注入
injectButton();

// 监听DOM变化,实时重注入
const observer = new MutationObserver(() => injectButton());
observer.observe(document.body, { childList: true, subtree: true });

2. 延迟注入,确保页面动态内容加载完成

调整脚本执行时机,等待页面完全渲染后再注入:

// 替换原有的main()调用
window.addEventListener('load', () => {
  // 延迟1秒确保动态内容渲染完毕,可根据实际情况调整时长
  setTimeout(injectButton, 1000);
});

3. 缩小监听范围(优化)

如果能找到input-group的父级稳定容器,可以缩小监听范围,减少性能消耗:

const parentContainer = document.querySelector('.some-stable-parent-class');
if (parentContainer) {
  observer.observe(parentContainer, { childList: true, subtree: true });
}

内容的提问来源于stack exchange,提问作者Mr. Quantum

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:50:40