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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM