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

Firefox扩展弹窗无法加载自定义HTML表格问题求助

Firefox扩展弹窗无法加载表格数据的问题排查与解决方案

我正在开发一款Firefox扩展,功能是读取YouTube主页(https://www.youtube.com/)的可见视频数据,提取视频ID、标题、时长、频道名称及频道ID,最终在扩展弹窗里以自定义HTML表格展示。目前遇到的问题是:弹窗始终显示默认的“Loading...”文本,popup.js代码未触发,控制台看不到错误日志,无法生成目标表格。

相关代码

manifest.json

{
  "manifest_version": 2,
  "name": "Ejemplo",
  "version": "1.0",
  "description": "Inspeccionar elementos de youtube.com.",
  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/main/beastify",
  "icons": {
    "48": "icons/border-48.png"
  },
  "applications": {
    "gecko": {
      "id": "manhunter45a45@example.com"
    }
  },
  "permissions": [
    "tabs",
    "activeTab",
    "storage",
    "background"
  ],
  "browser_action": {
    "default_icon": "icons/beasts-32.png",
    "default_title": "Obtain YouTube Info",
    "default_popup": "popup/results.html",
    "browser_style": true
  },
  "content_scripts": [
    {
      "matches": [
        "https://*.youtube.com/"
      ],
      "js": [
        "jquery-1.9.1.min.js",
        "Ejemplo.js",
        "/code/functions.js"
      ]
    }
  ],
  "background": {
    "scripts": [
      "/code/popup.js"
    ]
  }
}

results.html(弹窗页面)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div id="allVideos"><i>Loading...</i></div>
    <script src="../jquery-1.9.1.min.js"></script>
    <script src="../code/popup.js"></script>
</body>
</html>
(function () {
  console.log("Entró");
  init_code();
})();

/**
 * Function that initializes the page.
 */
function init_code() {
  try {
    // Initial variables: 
    var html_code = "";

    // Get all videos: 
    browser.storage.sync.get(['all_videos'])
      .then((result) => {
        if (result.hasOwnProperty('all_videos') && result.all_videos) {
          if (result.all_videos && result.all_videos.length) {
            // Build initial HTML table code: 
            html_code += `<table id="myTable"><tr><th>Thumbnail</th><th>Title</th><th>Channel</th><th>Channel_ID</th></tr>`;

            // Loop over the items and build the HTML with their data: 
            result.all_videos.forEach((item) => {
              html_code += appendItem(item);
            });

            // Finish the HTML table code: 
            html_code += "</table>";

          } else {
            // Show: "no items available": 
            html_code = '<strong>No videos are stored on the localStorage.</strong>';
          }
        } else {
          // Show: "no items available": 
          html_code = '<strong>No videos are stored on the localStorage.</strong>';
        }
      }, onErrorDetails);

    console.log("Ok!");

    // Show the results: 
    document.getElementById("allVideos").innerHTML = html_code;
  } catch (ex) {
    console.log("Error at the popup");
    console.log("Error: " + ex.message);
    console.log("Stack: " + ex.stack);
  }
}

/**
 * Function that builds the HTML to be added on the main HTML div.
 * @param {object} item The item (i.e, the object that contains the video's data).
 * @returns string
 */
function appendItem(item) {
  return `<tr><img src='${item.Thumbnail}' alt='${item.Title}' /></tr><tr><span>${item.Title}</span></tr><tr><span>${item.Channel}</span></tr><tr><span>${item.Channel_ID}</span></tr>`;
}

/**
 * Function that handles the error(s) - if any - when the info is obtained from the localStorage.
 * @param {object} error_dt The object with the error details.
 */
function onErrorDetails(error_dt) {
  console.log("Error!");
  console.log(error_dt);
}

核心问题分析

  1. 脚本上下文冲突:manifest.json中同时将popup.js放在background脚本和弹窗页面里,后台脚本的popup.js与弹窗的popup.js属于不同执行上下文,会导致逻辑混乱,且后台脚本不需要这个文件。
  2. 异步操作处理错误:browser.storage.sync.get是异步Promise操作,当前代码在Promise完成前就执行了innerHTML赋值,此时html_code还是初始空字符串,无法更新DOM。
  3. 表格HTML结构错误:appendItem函数返回多个独立的<tr>标签,每个数据单独占一行,不符合表格一行对应一条数据的结构,会导致渲染异常。
  4. 控制台查看方式错误:你可能查看的是YouTube页面的控制台,而非弹窗的控制台。弹窗的控制台需要右键点击弹窗空白处,选择“检查”才能打开。
  5. 数据存储验证缺失:未确认内容脚本(Ejemplo.js、functions.js)是否正确将提取的视频数据存入browser.storage.sync的all_videos字段。

修复步骤

1. 修正manifest.json

移除background字段中的popup.js,因为它是弹窗专属脚本,不需要在后台运行:

// 删除这段代码
"background": {
  "scripts": [
    "/code/popup.js"
  ]
}

2. 修复popup.js的异步逻辑

将DOM更新代码移到Promise的then回调内,确保拿到数据后再渲染:

function init_code() {
  try {
    browser.storage.sync.get(['all_videos'])
      .then((result) => {
        let html_code = "";
        if (result.hasOwnProperty('all_videos') && result.all_videos) {
          if (result.all_videos.length) {
            html_code += `<table id="myTable" class="s-table"><tr><th>Thumbnail</th><th>Title</th><th>Channel</th><th>Channel_ID</th></tr>`;
            result.all_videos.forEach((item) => {
              html_code += appendItem(item);
            });
            html_code += "</table>";
          } else {
            html_code = '<strong>No videos are stored.</strong>';
          }
        } else {
          html_code = '<strong>No videos are stored.</strong>';
        }
        // 拿到数据后再更新DOM
        document.getElementById("allVideos").innerHTML = html_code;
      }, onErrorDetails);
  } catch (ex) {
    console.log("Error at the popup");
    console.log("Error: " + ex.message);
    console.log("Stack: " + ex.stack);
    document.getElementById("allVideos").innerHTML = '<strong>Failed to load data.</strong>';
  }
}

3. 修正表格行结构

修改appendItem函数,将一条视频的所有数据放在同一个<tr>的<td>中:

function appendItem(item) {
  return `<tr>
            <td><img src='${item.Thumbnail}' alt='${item.Title}' style="width:80px;" /></td>
            <td>${item.Title}</td>
            <td>${item.Channel}</td>
            <td>${item.Channel_ID}</td>
          </tr>`;
}

4. 添加表格样式(可选)

在results.html的<head>中添加样式,匹配你需要的表格效果:

<style>
.s-table {
  border-collapse: collapse;
  width: 100%;
  margin-top: 10px;
}
.s-table th, .s-table td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}
.s-table th {
  background-color: #f2f2f2;
}
</style>

5. 验证数据存储

检查内容脚本是否正确执行了数据存储,比如在Ejemplo.js中确保有类似代码:

// 假设提取到的视频数据存在videos数组中
browser.storage.sync.set({all_videos: videos})
  .then(() => console.log("Videos stored successfully"))
  .catch(err => console.error("Storage error:", err));

6. 正确查看弹窗控制台

右键点击扩展弹窗的空白区域,选择“检查”,打开弹窗的开发者工具,查看console.log输出和错误信息。

关于弹窗HTML修改的确认

扩展的弹窗HTML完全可以通过JavaScript修改。弹窗是一个独立的HTML页面,拥有自己的DOM和执行上下文,和普通网页一样,你可以通过JavaScript任意操作DOM元素、修改内容或样式。

内容的提问来源于stack exchange,提问作者Mauricio Arias Olave

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:35:55