chrome浏览器扩展的事件处理
关于chrome扩展开发的栗子已经有很多了,问问度娘基本能满足你的欲望, 我想说的是扩展和页面间的数据传递问题。
我们知道写扩展有个必须的文件就是“manifest.json”, 这个里面定义了一个和页面打交道的文件“content.js”, 该js可以访问页面中的任何元素;但不幸的是页面却无法访问content.js中的任何方法(写扩展页面的除外啊,我说的页面是浏览器中的普通页面)。那么问题就来了:怎么才能触发content.js中的事件呢?
官方当然给出解决方案:content.js中写按钮的监听事件,比如一般button的click事件
1 //bt1 是页面按钮id 2 document.getElementById('bt1')..addEventListener(“click”,function(){ 3 //做一些自己的事情,和background.js打交道等等 4 },false);
这么做当然没有问题。
但是……
如果页面中没有bt1按钮呢 ?
如果我不知道是哪个按钮调用的呢 ?
或者说,content.js中有一个方法,需要页面上随时可以调用 。。。。
解决办法就是,页面添加一个固定的按钮就叫bt1,其他的都不能叫这个名字,content.js这样就可以绑定事件了, 谁用谁调用一下bt1的click事件。
其实还有个解决办法:自定义事件 , 看代码
1 //页面中定义一个事件 2 //name 事件名称,msg传递的消息值 3 createCustomEvent:function(name,msg){ 4 var evt = document.createEvent("CustomEvent"); 5 evt.initCustomEvent(name, true, false, msg); 6 document.dispatchEvent(evt); 7 },
content.js写一个事件监听
1 //content.js中的监听方法 2 //name要和页面name相同 3 //evt 就是得到的结果 4 document.addEventListener(name, function(evt) { 5 var data =evt.detail; //data就是上面的msg值 6 7 //todo 8 9 }
这样整个流程就通了,页面随时可以创建一个事件来调用扩展方法。
不过明白人已经看出来了,返回值呢? 是的,该方法只能传递值却不能得到结果,并且msg只能传递字符串,也没法定义回调。如果想得到返回值只能再content.js中也定义一个自定义事件,页面做监听,反过来使用上面的代码。(感觉很矬……)
这还没有完, 该方案不支持并发。当有两个地方同时调用该方法时,页面监听事件无法区分那个的返回值,得到的结果根本无法使用。
怎么办呢? 我又想到一个更矬的办法来,调用的时候传递一个回调,然后保存起来。
说不明白,看代码吧。页面代码
1 var sendMessage=function(msg,callback){ 2 //获取一个自增序列当key,页面唯一 3 var key=getIndex(); 4 //保存到hashtable里面,evtMap是个自定义hashtable 5 evtMap.add(key,callback); 6 //'调用自定义事件,把key带上 7 createCustomEvent(eventName,{"evtId":key,"msg":msg}); 8 9 }
content.js可以得到这个key,回调的时候再把这个可以传过来,看看content.js
1 document.addEventListener(listenerName, function(evt) { 2 3 var data =evt.detail; 4 //todo 得到msg 5 6 var res={"evtId":data.evtId,"msg":msg }; //把页面传递的key再传回去 7 8 var evt = document.createEvent("CustomEvent"); 9 evt.initCustomEvent(backEventName, true, false, res); 10 document.dispatchEvent(evt); 11 12 }, false);
再回到页面js代码
1 document.addListener(listenerName,function(response){ 2 //通过key从hasttable中再次获取callback函数 3 var evtId=response.evtId; 4 var callback=evtMap.getValue(evtId); 5 if (callback) { 6 callback(response.msg); 7 }; 8 });
上面就是一种比较矬的解决扩展和页面数据交互的一种方案,如果哪位高手有更好的方案不舍赐教~!! 感谢
下面把JS的Hashtable贴一下,其实度娘怀里就有
var HashTable=function(){ var size = 0; var entry = new Object(); this.add = function (key,value){ if(!this.containsKey(key)){ size ++ ; } entry[key] = value; } this.getValue = function (key) { return this.containsKey(key) ? entry[key] : null; } this.remove = function(key){ if( this.containsKey(key) && ( delete entry[key] ) ) { size --; } } this.containsKey = function(key){ return (key in entry); } this.containsValue = function(value){ for(var prop in entry) { if(entry[prop] == value){ return true; } } return false; } this.getValues = function () { var values = new Array(); for(var prop in entry) { values.push(entry[prop]); } return values; } this.getKeys = function () { var keys = new Array(); for(var prop in entry) { keys.push(prop); } return keys; } this.getSize = function () { return size; } this.clear = function () { size = 0; entry = new Object(); } }
————————————————————————————————————————
一个人的时候,总是在想
我的生活到底在期待什么……