Chrome 扩展程序中的选择和网站搜索

selection and site search in chrome extension

本文关键字:选择 网站搜索 扩展 程序 Chrome      更新时间:2023-09-26

我正在尝试编写接受用户选择的单词和用户定义的谷歌浏览器扩展程序网站并在该网站上搜索这个词(通过谷歌和上下文菜单)。选项页面中有一个表单。用户在表单字段中输入站点(字段/站点的数量可变 - 用户指定哪些站点,因此有多少个)。所有站点都保存到阵列中。数组被保存到 localStorage["arr"]。所有这些都在选项中.html。

在bg.html(背景页)首先,我从localStorage获取数组(现在一切都很好).然后我在循环中创建上下文菜单项。我只有一个用于所有上下文菜单项的 onclick 事件处理程序。在事件处理程序内部,我正在尝试获取正确的数组元素(在哪个站点上搜索)和 选择文本(要搜索的内容),然后打开一个包含 Google 搜索结果的新标签页。
我最大的问题:1)我根本无法获取数组元素(在事件处理程序中)!!(未定义要搜索的站点)。2)onclick事件仅适用于上下文菜单项之一。3)有时,上下文菜单项被创建,但单击根本不起作用!!

我的代码:manifest.json

{
  "name": "Context Site Search",
  "version" : "0.0.0.1",
  "background_page" : "bg.html",
  "options_page": "options.html",
  "permissions" : [
    "tabs",
    "contextMenus",
    "http://www.google.com"
    ]
}

BG.html:

<script type="text/javascript">
var ar = localStorage.getItem("arr").split(",");//getting array from localStorage 
for (var i=0;i<ar.length;i++){ // creating contextmenu items in a loop
chrome.contextMenus.create({
    "title": "find ' %s' в "+ ar[i],
    "contexts": [ "selection"],
    "onclick" : clickhandler
});
}
var clickhandler = function(e,ar){
var baseUrl = "http://www.google.com/search?q=site%3A";
if (e.selectionText){
baseUrl += ar[i]+ "&q="+ encodeURI(e.selectionText);
chrome.tabs.create(
{"url": baseUrl}
);
 }
}
</script>

请帮忙! 我做错了什么?? 如何解决这个问题??任何帮助,不胜感激。

提前感谢!!

更新:感谢serg,我终于得到了一些东西..但是有新的问题:1)上下文菜单项的数量神秘地翻了一番(甚至五元组!!在选项页面输入的站点。2)单击"保存"按钮不会立即用新菜单项替换旧菜单项。(重新加载显然需要扩展)。我怀疑,我错误地编写了在单击保存按钮时运行的保存函数......代码如下:

var arr = [];
function save() {
localStorage.clear();
var nodes = document.querySelectorAll("input[type=text]");
for (var i=0; i<nodes.length; i++){
    if (nodes[i].value == "" ){
        alert('Enter Data!');return false;
} else {
 arr.push( nodes[i].value);

   }}
localStorage['arr'] =  JSON.stringify(arr);
}

</script>

UPDATE2:

我想出了加倍/五倍的事情。 这取决于用户单击保存按钮的次数。1)有机会防止这种情况吗?例如,多次单击仅将一组值添加到数组中?2)上下文菜单项仍然没有改变。它们仅在重新加载扩展后才会更改。:((重新加载扩展和更改本地存储有什么区别?

当您将函数分配给onclick属性时,不会立即对其进行计算。当它被评估时,你的循环很久以前就结束了,ar[i]不包含你期望的内容。

这是一个经典的javascript问题,可以通过闭包来解决:

chrome.contextMenus.create({
    "title": "find ' %s' в "+ ar[i],
    "contexts": [ "selection"],
    "onclick" : (function(element) {
                    return function(info, tab) {
                        var baseUrl = "http://www.google.com/search?q=site%3A";
                        if (info.selectionText) {
                            baseUrl += element + "&q="+ encodeURI(info.selectionText);
                            chrome.tabs.create({"url": baseUrl});
                        }
                    }
                })(ar[i])
});

我们创建了匿名函数,该函数立即被计算并返回一个真实的事件处理程序。诀窍是当前ar[i]值现在将始终作为闭包内的变量element可用。

var ar = JSON.parse(localStorage.getItem("arr")); // you should also use JSON.stringify to store the array
var menuitems = []; // array to hold menu item ID's and sites
for (i in ar)
{
    menuitem = chrome.contextMenus.create({
        "title": "find ' %s' в " + ar[i],
        "contexts": ["selection"],
        "onclick": function(e)
        {
            var baseUrl = "http://www.google.com/search?q=site%3A";
            if (e.selectionText)
            {
                baseUrl += encodeURIComponent(menuitems[e.menuItemId]) + "&q=" + encodeURIComponent(e.selectionText);
                chrome.tabs.create({ "url": baseUrl });
            }
        }
    });
    menuitems[menuitem] = ar[i]; // store the ID of the current menuitem with the site
}

经过测试,这应该可以解决问题。请注意,我还添加了一些改进,例如对循环使用 for (.. in ..),对 URL 参数使用 encodeURIComponentencodeURI用于完整的 URL,encodeURIComponent用于 URI 组件,即参数)。此外,使用 JSON 在 localStorage 中存储数据。

我认为您做错的是您在创建菜单项定义了clickHandler。创建菜单项时,clickHandler为 null,单击它时不会发生任何反应。我通过在菜单项创建中简单地定义内联函数来解决此问题。