chrome瀏覽器擴展的事件處理

關於chrome擴展開發的栗子已經有不少了,問問度娘基本能知足你的慾望, 我想說的是擴展和頁面間的數據傳遞問題。chrome

咱們知道寫擴展有個必須的文件就是「manifest.json」, 這個裏面定義了一個和頁面打交道的文件「content.js」, 該js能夠訪問頁面中的任何元素;但不幸的是頁面卻沒法訪問content.js中的任何方法(寫擴展頁面的除外啊,我說的頁面是瀏覽器中的普通頁面)。那麼問題就來了:怎麼才能觸發content.js中的事件呢?json

官方固然給出解決方案:content.js中寫按鈕的監聽事件,好比通常button的click事件瀏覽器

1 //bt1 是頁面按鈕id
2 document.getElementById('bt1')..addEventListener(「click」,function(){
3     //作一些本身的事情,和background.js打交道等等
4 },false);

這麼作固然沒有問題。併發

可是……ide

若是頁面中沒有bt1按鈕呢 ?函數

若是我不知道是哪一個按鈕調用的呢 ?this

或者說,content.js中有一個方法,須要頁面上隨時能夠調用 。。。。spa

解決辦法就是,頁面添加一個固定的按鈕就叫bt1,其餘的都不能叫這個名字,content.js這樣就能夠綁定事件了, 誰用誰調用一下bt1的click事件。code

 

其實還有個解決辦法:自定義事件 , 看代碼blog

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
相關文章
相關標籤/搜索