要实现在谷歌浏览器所有标签页的搜索框 批量搜索内容,以下请指导如何解决?

功能目标:同时在谷歌浏览器的所有打开的标签页的搜索框里搜索内容
遗留bug:任一标签网页需要先在当前页面搜索过后,才能被统一同步批量搜索
遗留优化点:使鼠标点击插件图标后 自动定位到搜索框

文件结构:
multi-tab-search/
├── manifest.json
├── popup.html
├── popup.js
├── background.js
├── content.js
└── icon.png

manifest.json文件内容:
{

"manifest_version": 2,
"name": "Multi Tab Search",
"version": "1.0",
"permissions": [
    "tabs",
    "activeTab"
],
"browser_action": {
    "default_popup": "popup.html",
    "default_icon": {
        "16": "icon.png",
        "48": "icon.png",
        "128": "icon.png"
    }
},
"background": {
    "scripts": ["background.js"],
    "persistent": false
}

}

background.js文件内容:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {

if (request.query) {
    chrome.tabs.query({}, function(tabs) {
        tabs.forEach(function(tab) {
            chrome.tabs.executeScript(tab.id, {
                code: `
                    var searchBoxes = document.querySelectorAll('input[type="search"], input[name="q"], input[title="搜索"], input[placeholder="Search"]');
                    if (searchBoxes.length > 0) {
                        searchBoxes[0].value = "${request.query}";
                        var form = searchBoxes[0].closest('form');
                        if (form) {
                            form.submit();
                        } else {
                            searchBoxes[0].dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'}));
                        }
                    }
                `
            });
        });
    });
}

});

content.js文件内容:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {

if (request.query) {
    searchInPage(request.query);
}

});

function searchInPage(query) {

// 定义搜索操作的函数
const searchBoxes = document.querySelectorAll('input[type="search"], input[name="q"], input[title="搜索"], input[placeholder="Search"]');
if (searchBoxes.length > 0) {
    searchBoxes[0].value = query;
    const form = searchBoxes[0].closest('form');
    if (form) {
        form.submit();
    } else {
        searchBoxes[0].dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'}));
    }
} else {
    console.log("No searchable input field found on this page.");
}

}

popup.html文件内容:
<!DOCTYPE html>
<html>
<head>

<title>Multi Tab Search</title>
<style>
    body {
        width: 200px;
        padding: 10px;
    }
    input {
        width: calc(100% - 22px);
        padding: 5px;
    }
    button {
        width: 100%;
        padding: 5px;
        margin-top: 10px;
    }
</style>

</head>
<body>

<input type="text" id="searchQuery" placeholder="Enter search query">
<button id="searchBtn">Search</button>
<script src="popup.js"></script>

</body>
</html>

popup.js文件内容:
document.getElementById('searchBtn').addEventListener('click', function() {

var searchQuery = document.getElementById('searchQuery').value;
searchTabs(searchQuery);

});

document.getElementById('searchQuery').addEventListener('keydown', function(event) {

if (event.key === 'Enter') {
    var searchQuery = document.getElementById('searchQuery').value;
    searchTabs(searchQuery);
}

});

function searchTabs(query) {

chrome.runtime.sendMessage({query: query});

}

阅读 794
avatarAI BotBETA

要解决你的问题,我们可以从几个方面进行优化和修复:

  1. 解决遗留bug:确保即使标签页没有在当前页面进行过搜索,也能被批量搜索。
  2. 优化插件图标点击后的行为:点击插件图标时,不直接打开popup.html,而是直接执行搜索(可选,取决于用户需求)。

解决方案

1. 解决遗留bug

你的 background.js 文件中的代码已经能够遍历所有标签页并尝试在它们的搜索框中输入搜索词。但是,确保这些标签页都是可访问的(即没有被浏览器或页面本身限制)是很重要的。此外,确保 content.js 在每个标签页中都被正确加载和执行。

你可以通过确保 content.js 被注入到所有需要的标签页中来解决这个问题。这通常是通过在 manifest.json 中添加 "content_scripts" 部分来实现的,但你也可以在 background.js 中动态注入脚本。

2. 优化插件图标点击后的行为

如果你希望点击插件图标直接触发搜索,而不是打开popup.html,你可以修改 browser_action 的配置,使其不打开popup,并在 background.js 中监听一个不同的事件(如 chrome.browserAction.onClicked)来触发搜索。

但是,基于你当前的实现,我们可以保留popup.html作为用户界面,并在其中进行搜索。

修改后的 manifest.json(可选)

如果你决定使用 content_scripts 来确保 content.js 在所有页面加载时执行,可以添加如下配置:

"content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": ["content.js"]
    }
],

但是,由于你已经在 background.js 中通过 chrome.tabs.executeScript 动态注入了脚本,这一步可能是可选的。

修改后的 background.js(无需修改)

你的 background.js 文件看起来已经能够处理搜索请求,因此无需修改。

修改后的 popup.js(无需修改)

你的 popup.js 文件也足够处理从popup.html接收搜索请求并发送到所有标签页的功能。

结论

你的实现已经相当接近目标功能,主要问题是确保 content.js 在所有需要的标签页中正确执行。如果你遇到任何标签页无法被搜索的问题,请检查这些标签页是否有任何阻止脚本执行的安全设置或内容安全策略(CSP)。

此外,如果你想要进一步优化用户体验,可以考虑添加一些错误处理逻辑来捕获并通知用户哪些标签页无法被搜索,以及为什么。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题