上網時經常在多個搜尋引擎間切換,但使用chrome內建的搜尋引擎切換比較麻煩,換一個引擎就需要設定一次配置,因此也在chrome市集找了多個搜尋擴充程式,使用下來都是各有優點,但不能同時具備我想要的功能,例如功能表項目分組、劃詞搜尋、添加自訂搜尋或是不同電腦間同步配置,多少都有點缺憾,所以決定自己動手豐衣足食,實現一個右鍵菜單擴充程式,基本特性如下: 右鍵菜單搜尋 頁面劃詞搜尋 菜單分組顯示 自訂添加搜尋引擎 同步配置 chrome軟體市集擴充地址,歡迎大家安裝試用: Context Search 擴充程式:下面對代碼實現做個介紹 1 在chrome右鍵操作功能表增加自訂功能表項目使用chrome.contextMenus.create建立操作功能表。1) 建立主功能表項目 [javascript] var context = "selection"; var id = chrome.contextMenus.create({ "title" : J.NAME, "id" : "c" + context, "contexts" :[context] }); "title": 功能表項目顯示標題"id": 菜單id"contexts": 設定菜單對應的操作內容,可以設定一個或多個內容: ["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"] 本擴充程式使用"selection",也就是當前選擇的文本。本功能表項目不響應操作事件。 2) 建立分組菜單 [javascript] catalogId = chrome.contextMenus.create({ "title" : catalog, "id" : "c" + catalog, "contexts" : [context], "parentId" : id }); parentId: 與建立主菜單方式相比多了一個"parentId"參數,說明父功能表項目的id,也就是主功能表項目的id;本功能表項目不響應操作事件。3) 建立子功能表項[javascript] chrome.contextMenus.create({ "title" : J.SEARCHENGINES[i].ID, "id" : i.toString(), "contexts" :[context], "parentId" : catalogId, "enabled" : J.SEARCHENGINES[i].ENABLE, "onclick" : onClickMenu }); "enabled": 表示功能表項目是否可用;"onclick": 表示該功能表項目的點擊事件處理函數,當該子功能表項點擊時onClickMenu()函數被調用。2 頁面劃詞搜尋需要在頁面載入時載入context.js,增加滑鼠操作的監聽。監視頁面滑鼠左鍵點擊動作,當滑鼠左鍵mouseup事件產生時顯示搜尋菜單。[javascript] document.addEventListener("mouseup", function() { ... // 只處理滑鼠左鍵,其他鍵按下時如果有菜單,則刪除菜單 if (event.button != 0) { if(searchMenu) { document.body.removeChild(searchMenu); } return; } ... // 讀取配置,建立菜單 chrome.extension.sendRequest({cmd: 'get_options'}, function(opts) { createSearchMenu(opts, x, y); }); }); 菜單動態建立。3 菜單分組擴充程式使用JSON格式的配置:{"CATALOG":"","ID":"Google(安全)","URL":"https://www.google.com.hk/search?q=%s","ENCODE":false,"ENABLE":true}CATALOG 類型說明菜單分組,包含以下項:Null 字元: 表示不分組,直接是主菜單的子項; -: 表示分隔線; 字串: 表示分組名稱;4 同步配置使用sync同步到伺服器,需要gmail帳號登入同步。另外儲存配置時如果長度超出QUOTA_BYTES_PER_ITEM限制,需要分區儲存。[javascript] var Storage = chrome.storage.sync; // 儲存配置到Storage,超過QUOTA_BYTES_PER_ITEM需要進行分區儲存。 function setOptions(opts, cb) { var optionStr = JSON.stringify(opts); var length = optionStr.length; var sliceLength = Storage.QUOTA_BYTES_PER_ITEM / 2; // 簡單設定每個分區最大長度,保證能儲存 var optionSlices = {}; // 儲存分區資料 var i = 0; // 分區序號 // 分區儲存資料 while (length > 0) { optionSlices["cs_options_" + i] = optionStr.substr(i * sliceLength, sliceLength); length -= sliceLength; i++; } // 儲存分區數量 optionSlices["cs_options_num"] = i; // 寫入Storage Storage.set(optionSlices, cb); //console.log(optionSlices); }