關於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(); } }