在Chrome扩展中选择和站点搜索 [英] selection and site search in chrome extension

查看:83
本文介绍了在Chrome扩展中选择和站点搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写google chrome扩展程序,它接受用户选择的单词和用户定义的
网站并在该网站上搜索该单词(通过Google和contextmenu)。选项页面中有一个表单。
用户在表单字段中输入网站(可变数量的字段/网站 - 用户指定
哪些网站以及多少个)。所有网站都保存到数组中。数组被保存到localStorage [arr]。所有这些都在options.html中。



在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(,); //从localStorage获取数组
$ b $ for(var i = 0; i< ar.length; i ++){//在循环中创建contextmenu项目

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)神秘的双选项(甚至quintuples !!)网站在选项页面输入的数量的contextmenu项目。
2)单击保存按钮不会立即替换旧的菜单项(显然需要重新加载$ ​​b $ b扩展名)。
i嫌疑人,我错误地写了保存功能,它运行后保存按钮点击...
这里的代码:

  var arr = []; 
函数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!') ;返回false;
} else {
arr.push(nodes [i] .value);


}}

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

}


< / script>

UPDATE2:



/ quintupling的东西。这取决于用户点击保存按钮的次数。
1)是否有机会阻止此?例如多次点击只添加一组值到数组?
2)上下文菜单项目不会更改。他们改变ONLY后重新加载扩展..:((
)重新加载扩展和改变localStorage之间的区别是什么?

解决方案

当你为 onclick 属性赋值时,它不会立即被评估,当它被评估时,你的循环很久以前就会结束,



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



  chrome.contextMenus.create({
title:find'%s'в+ ar [i],
contexts:[selection],
onclick:(function(element){
return function(info,tab){
var baseUrl =http:/ / info.selectionText {
aseUrl + = element +& q =+ encodeURI(info .selectionText);
chrome.t abs.create({url:baseUrl});
}
}
})(ar [i])
});

我们创建了一个匿名函数,它被立即评估并返回一个真实的事件处理函数。诀窍在于当前 ar [i] 值现在总是可以在闭包中作为元素变量使用。


I'm trying to write google chrome extension that accepts user-selected word and user-defined web site and searches this word on that site (via Google and contextmenu).There's a form in options page. User enters sites in form fields (there's a variable number of fields/sites- user specifies which sites and therefore how many).All sites are saved to array. array is saved to localStorage["arr"]. all of this was in options.html.

On bg.html (Background page) first of all, i get array from localStorage (all is fine by now).then i create contextmenu items in a loop. I have ONLY ONE onclick event handler for all contextmenu items. Inside of event handler, i'm trying to get the right array element (on which site to search) and selectontext(what to search), and then open a new tab with google search results.
My BIGGEST problems: 1)i can't get array element (in event handler) at all!!(on which site to search is undefined). 2)onclick event works only for one of context menu items. 3)sometimes, contextmenu items are created but clicking doesn't work at all!!

My code: 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>

Please, help! what am i doing wrong?? how to fix this?? Any help is appreciated.

Thanks in advance!!

UPDATE: Thanks to serg, i'm finally getting something.. but there are new issues: 1) number of contextmenu items mysteriously doubles (and even quintuples!! )sites entered at options page. 2)clicking save button doesn't immediately replace old menuitems with new ones.(Reloading extension is obviously needed). i suspect, i incorrectly wrote save function which runs upon save button click... here's code:

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:

i figured out doubling/quintupling thing. it depends on how many times user clicks save button.. 1)Is there a chance to prevent this?? e.g. multiple clicks add ONLY ONE set of values to array?? 2)Contextmenu items still don't change. they change ONLY AFTER reloading extension.. :(( What is the difference between reloading extension and changing localStorage??

解决方案

When you assign a function to onclick property it is not evaluated right away. By the time it is evaluated your loop is ended long time ago and ar[i] doesn't contain what you expect.

It is a classic javascript problem which is solved with closures:

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])
});

We created anonymous function which is evaluated right away and returns a real event handler. The trick is that current ar[i] value will now be always available as element variable inside the closure.

这篇关于在Chrome扩展中选择和站点搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆