如何从Chrome扩展弹窗可靠获取最后聚焦的标签页?
Chrome扩展弹窗中可靠获取最后聚焦标签页的轻量方案
需求
在Chrome扩展弹窗环境中,通过chrome.tabs.query(tabQueryOptions)可靠获取最后聚焦的非弹窗标签页,且方案需尽可能轻量,避免高资源占用。
现有方案的问题
当前通过监听或超时机制将最后聚焦的非弹窗标签页存入Chrome Storage供弹窗调用,但该方案资源占用较高,不符合轻量需求。
已尝试的查询选项及失效场景
{lastFocusedWindow: true, active: true}:从其他页面切换到弹窗/点击按钮时失效{active: true, currentWindow: true}:从其他窗口/标签页切换到弹窗时失效{pinned: true, active: true}:打开弹窗后原标签页不再处于活跃状态,因此失效{pinned: true}:请求无响应,返回的标签列表顺序随机
复现代码与步骤
代码文件
popup.js
(async function onButtonClick(){ document.getElementById('get_active_tab').addEventListener('click', async () => { chrome.runtime.sendMessage('get active tab pretty pleeeeease') }) })()
popup.html
<!DOCTYPE html> <head> </head> <body> <div class="extension"> <div class="selection__container"> <button id="get_active_tab" style="height: 100%; width: 100%; font-size: 3rem"> CLICK TO GET ACTIVE TAB </button> </div> </div> </body> <script src="popup.js"> </script> </html>
manifest.json
{ "name": "Test Extension", "description": "Testing Tab Query", "version": "1.00", "manifest_version": 3, "background": { "service_worker": "background.js" }, "permissions": [ "storage", "activeTab", "identity", "contextMenus", "webRequest", "tabs", "clipboardWrite" ], "host_permissions": [ "<all_urls>" ], "action": { "default_popup": "popup.html" } }
background.js
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => { if(message === 'get active tab pretty pleeeeease'){ let currentWindow = await chrome.windows.getCurrent() let [currentTab] = await chrome.tabs.query({active: true, windowId: currentWindow.id}) console.log(`Current tab URL: ${currentTab.url}`) sendResponse(currentTab.url) } })
复现步骤
- 本地加载已解压的扩展程序
- 打开一个有效标签页
- 打开弹窗并打开开发者工具查看日志,点击按钮
- 打开新Chrome窗口并创建新的有效标签页
- 再次打开弹窗并点击按钮
- 观察日志结果
- 在不同窗口/标签页间切换、关闭窗口等操作,持续观察日志内容
轻量解决方案
核心思路:利用Chrome原生API获取最后聚焦窗口,同时过滤掉扩展内部页面(包括弹窗),仅保留实际网页标签。
修改background.js代码如下:
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => { if(message === 'get active tab pretty pleeeeease'){ // 获取最后聚焦的窗口,同时返回窗口内的标签列表 const lastFocusedWindow = await chrome.windows.getLastFocused({populate: true}); // 筛选最后聚焦窗口中的活跃网页标签(排除chrome://等内部页面) const targetTabs = await chrome.tabs.query({ active: true, windowId: lastFocusedWindow.id, url: ["http://*/*", "https://*/*"] }); if(targetTabs.length > 0){ console.log(`Last focused tab URL: ${targetTabs[0].url}`) sendResponse(targetTabs[0].url); } else { // 降级处理:若无活跃网页标签,返回窗口内第一个有效网页标签 const fallbackTabs = lastFocusedWindow.tabs.filter(tab => tab.url.startsWith('http://') || tab.url.startsWith('https://') ); if(fallbackTabs.length > 0){ console.log(`Fallback tab URL: ${fallbackTabs[0].url}`) sendResponse(fallbackTabs[0].url); } else { sendResponse(null); } } } return true; // 确保异步sendResponse正常生效 })
方案优势
- 无需持续监听标签页/窗口事件,仅在弹窗触发时执行查询,资源占用极低
- 直接调用Chrome原生API获取最后聚焦窗口,避免Storage读写开销
- 通过URL过滤精准获取实际网页标签,排除扩展内部页面及弹窗本身
内容的提问来源于stack exchange,提问作者Callum
相关产品推荐
相关产品推荐

