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();
        }
    }
View Code

 

posted @ 2015-09-11 15:41  卒子  阅读(3612)  评论(0编辑  收藏  举报