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

Chrome扩展如何调用Tampermonkey脚本内自定义函数

答案

该需求完全可以实现。
Chrome扩展弹窗运行在独立的扩展上下文,@grant none模式下的Tampermonkey脚本运行在页面主世界上下文,二者默认隔离无法直接访问对方的变量/函数,通过自定义DOM事件做跨上下文通信即可完成调用,你现有manifest申请的activeTab、scripting权限已经完全满足需求,不需要额外配置权限。

具体实现步骤

1. 修复现有文件的语法问题

你提供的manifest.json存在几处语法错误,先修复:

  • permissions数组最后一项"webRequestBlocking"后补全缺失的数组闭合
  • action.default_popup、icons配置下的所有路径字符串补全缺失的闭合双引号
  • Tampermonkey脚本的@match原配置为http://*/*,仅匹配http站点,修改为*://*/*即可覆盖所有http/https站点,避免https站点下脚本不生效。

2. 修改Tampermonkey脚本

原脚本中createFolder是立即执行函数内的局部变量,外部无法访问。需要将待调用函数挂载到window对象(方便控制台调试),同时添加自定义事件监听,响应扩展发来的调用指令:

// ==UserScript==
// @name         All functions
// @namespace    http://tampermonkey.net/
// @version      0.1
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function createFolder() {
        try {
            var folderName = prompt('Folder Name');
            if (!folderName) return;

            var jsZip = document.createElement('script');
            jsZip.type = 'text/javascript';
            jsZip.src = 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.0/jszip.js';
            jsZip.className = 'jsZip';
            document.body.appendChild(jsZip);

            var fileSaver = document.createElement('script');
            fileSaver.type = 'text/javascript';
            fileSaver.src = 'https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.js';
            fileSaver.className = 'fileSaver';
            document.body.appendChild(fileSaver);

            setTimeout(function () {
                var zip = new JSZip();
                zip.folder(folderName).file("myFile.js", `code code code`);

                zip.generateAsync({
                        type: "blob"
                    })
                    .then(function (content) {
                        saveAs(content, folderName);
                    });
            }, 1000);
        } catch (error) {
            console.log('%c ---      ' + error + '      --- ',
                'background: black; color: white; font-size: 15px; font-family: monospace; padding: 0px;');
        }
    }

    // 挂载到window,控制台可直接调用
    window.createFolder = createFolder;
    // 监听扩展触发的自定义事件
    window.addEventListener('callTMCreateFolder', createFolder);
})();

3. 调整popup.html

原文件未引入脚本、也未给点击区域绑定交互,修改后如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Interface</title>
  <meta charset="UTF-8">
  <style>
    .button-container {
      cursor: pointer;
      padding: 10px;
    }
    .button-img {
      display: block;
      width: 32px;
      height: 32px;
    }
  </style>
</head>
<body>
  <div class="row">
    <div class="button-container" id="createFolderBtn">
      <img class="button-img" src="button-img.png" alt="创建文件夹">
    </div>
  </div>
  <script src="popup.js"></script>
</body>
</html>

4. 新建popup.js处理点击逻辑

绑定按钮点击事件,点击时获取当前激活标签页,直接向页面主世界注入脚本派发自定义事件,触发油猴中的函数执行:

document.getElementById('createFolderBtn').addEventListener('click', async () => {
  // 获取当前窗口激活的标签页
  const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
  if (!activeTab.id) return;

  // 注入脚本到页面主世界(和油猴脚本同上下文),派发事件触发函数
  await chrome.scripting.executeScript({
    target: { tabId: activeTab.id },
    world: 'MAIN',
    func: () => {
      window.dispatchEvent(new CustomEvent('callTMCreateFolder'));
    }
  });

  // 执行后自动关闭弹窗
  window.close();
});

补充说明

  • 必须保持Tampermonkey脚本的@grant none配置,否则脚本会运行在油猴的独立沙箱中,无法收到页面主世界派发的事件
  • 如果需要从扩展向油猴函数传递参数,可在CustomEvent初始化时将参数放入detail字段,油猴侧的事件回调中通过e.detail读取即可
  • 测试时需要先在Chrome扩展管理页开启开发者模式、重新加载修改后的扩展,同时刷新目标页面让Tampermonkey脚本重新注入生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:15:40