2011-04-06 57 views
1

我试图写谷歌Chrome扩展,接受用户选择的词和用户定义的 网站,并在该网站上搜索该词(通过谷歌和contextmenu)。有一种形式选项页面。 用户在表单字段中输入网站(可变数量的字段/网站 - 用户指定 哪些网站,因此有多少)。所有网站都保存到数组中。数组被保存到localStorage [“arr”]。所有这些都在options.html中。在Chrome扩展中的选择和网站搜索

在bg.html(背景页) 首先,我从localStorage获得数组(现在一切都很好)。然后我在循环中创建contextmenu项目。我只有一个onclick事件处理程序的所有contextmenu项目。 在事件处理程序中,我试图获取正确的数组元素(在哪个网站上搜索) 和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)在选项页面输入的contextmenu项目数量神秘地增加了一倍(甚至五倍多!!)。 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

+0

如果您需要更改上下文菜单项,只需使用'chrome.contextMenus.removeAll'删除所有内容并重新创建它们。更新中的代码看起来不错,问题在其他地方。 – serg 2011-04-06 16:59:56

+0

是否可以在save()的开始处使用localStorage.clear()? – DrStrangeLove 2011-04-06 17:09:01

+0

我认为没有必要,无论如何你都会覆盖旧的价值。 – serg 2011-04-06 19:08:00

回答

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为空,单击时没有任何反应。我通过在菜单项创建中简单定义内联函数来解决这个问题。

+0

它的工作原理,但很差。只在一个网站上的任何菜单项搜索。 – DrStrangeLove 2011-04-06 16:01:43

+0

@DrStrangeLove,你是对的,显然我没有对它进行彻底的测试。在工作版本中编辑。 – 2011-04-06 16:42:06

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

+0

谢谢!请参阅更新,请.. – DrStrangeLove 2011-04-06 16:53:27