如何使用chrome.scripting API在当前标签页执行脚本?遇tab未定义错误
问题描述
我正在为基于Chromium内核的浏览器开发一款简单的自动点击器,采用Manifest V3的activeTab和scripting权限。
需求目标
按下Alt+Shift+K快捷键启动自动点击器,再次按下则停止。
遇到的错误
按下Alt+Shift+K激活当前标签页的扩展时,service worker控制台返回如下错误:
Uncaught (in promise) ReferenceError: tab is not defined
Context
service-worker.js
Stack Trace
service-worker.js:11 (anonymous function):Line 11: target: { tabId: tab.id },
已尝试的操作
我想遵循最佳实践,参考官方API文档中使用function getTabId() { ... }获取扩展运行标签页的方法,但不确定是不是作用域问题,相信有简单的解决办法。
源码
manifest.json
{ "manifest_version": 3, "name": "Autoclicker", "description": "A simple auto clicker.", "version": "0.1", "author": "name@example.com", "permissions": [ "activeTab", "scripting" ], "background": { "service_worker": "service-worker.js" }, "commands": { "toggle-auto-clicker": { "description": "Toggle auto clicker", "suggested_key": { "default": "Alt+Shift+K" } } } }
service-worker.js
let autoClickerEnabled = false; // Toggle auto clicker chrome.commands.onCommand.addListener(async (command) => { if (command === "toggle-auto-clicker") { autoClickerEnabled = !autoClickerEnabled; console.log("AutoClicker is now " + (autoClickerEnabled ? "enabled" : "disabled")); if (autoClickerEnabled) { chrome.scripting.executeScript({ target: { tabId: tab.id }, // <-- error on this line files: ['scripts/auto-clicker.js'], }) .then(() => console.log("injected scripts/auto-clicker.js")) .catch(err => console.error("Script injection failed: ", err)); } } });
auto-clicker.js
if (typeof autoClickerInterval === 'undefined') { let autoClickerInterval = false; } document.addEventListener('mousemove', (event) => { let mousePosition = { x: event.clientX, y: event.clientY }; }); function simulateClick() {// snip} function startAutoClicker() {// snip} function stopAutoClicker() {// snip} chrome.runtime.onMessage.addListener((message) => { if (message === 'startAutoClicker') { startAutoClicker(); } if (message === 'stopAutoClicker') { stopAutoClicker(); } });
解决方案
错误原因很明确:service-worker.js中直接使用tab.id,但tab变量从未定义。要解决这个问题,需要通过chrome.tabs.query()获取当前活跃标签页的ID,同时补充停止点击的逻辑,并修复内容脚本的作用域问题。
修改后的service-worker.js
let autoClickerEnabled = false; chrome.commands.onCommand.addListener(async (command) => { if (command === "toggle-auto-clicker") { autoClickerEnabled = !autoClickerEnabled; console.log("AutoClicker is now " + (autoClickerEnabled ? "enabled" : "disabled")); // 获取当前活跃标签页 const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (autoClickerEnabled) { chrome.scripting.executeScript({ target: { tabId: activeTab.id }, files: ['scripts/auto-clicker.js'], }) .then(() => console.log("injected scripts/auto-clicker.js")) .catch(err => console.error("Script injection failed: ", err)); } else { // 向内容脚本发送停止指令 chrome.tabs.sendMessage(activeTab.id, 'stopAutoClicker'); } } });
修改后的auto-clicker.js
// 提升变量到全局作用域,确保函数间可访问 let autoClickerInterval; let mousePosition = { x: 0, y: 0 }; document.addEventListener('mousemove', (event) => { mousePosition = { x: event.clientX, y: event.clientY }; }); function simulateClick() { // 模拟鼠标点击当前位置 const clickTarget = document.elementFromPoint(mousePosition.x, mousePosition.y); if (clickTarget) { const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, clientX: mousePosition.x, clientY: mousePosition.y }); clickTarget.dispatchEvent(clickEvent); } } function startAutoClicker() { if (!autoClickerInterval) { // 每100ms点击一次,可根据需求调整间隔 autoClickerInterval = setInterval(simulateClick, 100); } } function stopAutoClicker() { if (autoClickerInterval) { clearInterval(autoClickerInterval); autoClickerInterval = null; } } chrome.runtime.onMessage.addListener((message) => { if (message === 'startAutoClicker') { startAutoClicker(); } if (message === 'stopAutoClicker') { stopAutoClicker(); } });
关键修改点
- 通过
chrome.tabs.query({ active: true, currentWindow: true })获取当前活跃标签页,解决tab未定义的问题。 - 补充停止自动点击的逻辑:向内容脚本发送
stopAutoClicker消息。 - 修复内容脚本的变量作用域问题,将
autoClickerInterval和mousePosition提升到全局,确保函数间正常访问。 - 完善
simulateClick函数的实现,让点击逻辑可正常运行。
内容的提问来源于stack exchange,提问作者user14854027
相关产品推荐
相关产品推荐

