chrome扩展中的选择和站点搜索

时间:2011-04-06 13:50:07

标签: javascript google-chrome-extension

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

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

我的代码: 的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)Contextmenu项目仍然没有变化。它们只在重新加载扩展后改变.. :(( 重新加载扩展和更改localStorage有什么区别??

2 个答案:

答案 0 :(得分:1)

将功能分配给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变量。

答案 1 :(得分:0)

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 ..)作为循环,encodeURIComponent表示URL参数(encodeURI表示完整的URL,encodeURIComponent表示URI组件,即参数)。此外,使用JSON在localStorage中存储数据。

我认为你做错了是你在创建菜单项后定义了clickHandler 。创建菜单项时,clickHandler为空,单击它时没有任何反应。我通过简单地在菜单项创建中定义内联函数来解决这个问题。