<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] # Google Chrome擴展簡介 Google Chrome擴展是一種軟件,以增強Chrome瀏覽器的功能,它是**以chrome瀏覽器為宿主運行**的一個web程序。 Google Chrome擴展使用HTML、JavaScript、CSS和圖片等Web技術開發。 ## 擴展(Extension)與插件(Plugin) Google Chrome擴展與Google Chrome插件不同。 1. Google Chrome擴展無需了解瀏覽器的源代碼,用JS開發。 2. Google Chrome插件是更底層的瀏覽器功能擴展,需要深入掌握瀏覽器的源代碼,用C/C++開發。 這意味著 Plugin 以Native Code運行,在性能上要優于 Extension,適合執行**計算密集型**工作。不過,以 Native Code 運行,使得 Plugin 在安全上面臨更大挑戰。 ## 兩種類型的 Plugin Chromium最初支持兩種類型的 Plugin:NPAPI Plugin 和 PPAPI Plugin。 1. NPAPI 全稱是Netscape Plugin Application Programming interface。 2. PPAPI 全稱是Pepper Plugin Application Programming Interface。 從表面上看,兩者的區別在于使用了不同的API規范。其中,NPAPI來自于Mozilla,而PPAPI來自于Google。但實際上,**PPAPI與另外一種稱為Native Client(NaCl)的技術是緊密聯系在一起的**。 [NPAPI 為什么會被 Chrome 禁用?受影響的網站有什么普遍性?](https://www.zhihu.com/question/31227185?rf=30953196) # Chrome擴展的基本組成 至少包括一個 `manifest.json` 和一個 `js 文件` * **manifest.json 是擴展的調度中心,用于聲明各種資源。該文件采用JSON格式定義** * js 文件中定義要執行的操作 Google Chrome擴展,通常還可以包括圖標、頁面和CSS等資源 * 圖標通常是`19px*19px`的PNG文件 * 頁面通常是HTML文件,用于定義顯示給用戶的窗口,如popup頁面或options頁面等 ## Manifest 示例: ```js { "manifest_version": 2, "name": "我的時鐘", "version": "1.0", "description": "我的第一個Chrome擴展", "icons": { "16": "images/icon16.png", "48": "images/icon48.png", "128": "images/icon128.png" }, "browser_action": { "default_icon": { "19": "images/icon19.png", "38": "images/icon38.png" }, "default_title": "我的時鐘", "default_popup": "popup.html" } ``` `manifest.json`文件,就是一個json格式標準的文件。 1. name **必須**,用來標識擴展的簡短純文本。這個文字將出現在安裝對話框,擴展管理界面,和store里面 2. version **必須**,定義了擴展的版本,用一個到4個數字來表示,中間用點隔開。 3. manifest_version **必須**,表示manifest文件自身格式的版本號。從Chrome 18開始,必須指定版本號為數字`2` 4. description 定義了插件的詳細描述信息 5. app 對象定義了要打開的URL地址 6. iocns 對象定義了幾種不同尺寸的圖標的地址 7. requirements 對象定義了需要用到資源權限 8. browser_action為設置擴展在瀏覽器右上角的一些動作,比如鼠標懸停展示的標題default_title、鼠標點擊展示的頁面default_popup等。 9. 文件中出現了兩個icons的key,第一個為在瀏覽器擴展頁面上展示的圖標,第二個default_icons為在瀏覽器右上角展示的圖標。 10. 我們需要新建一個images文件夾,并放入一些圖標文件。 # 開發&測試你的擴展 還好,有一種方法可以測試您的擴展, 而不必將其發布到 Chrome 的 web 商店。在 chrome 瀏覽器的地址欄中, 只需鍵入: ~~~ chrome://extensions ~~~ 勾選 **Developer mode**,然后點擊**Load unpacked extension...**按鈕。然后選擇存放你開發擴展文件的工作目錄。 ![](https://img.kancloud.cn/bd/c1/bdc103efd6ba471525c3c8ddd6359407_600x86.png) 記住:每次修改了代碼要重新加載擴展。 # Chrome 擴展架構 如下圖示,一個Chrome 擴展的架構: ![the architecture](https://img.kancloud.cn/56/71/5671155ac49515bcb2949bf95b825a89_600x223.png) ## Background Pages 每個擴展都有一個不可見的后臺頁面由瀏覽器運行,每個擴展都有一個由瀏覽器運行的不可見的后臺頁面。 有兩種類型——**持久的后臺頁面**和**事件頁面**。 第一種,會一直保持在后臺活動的狀態。 第二種,只有在需要時才會活動。 Google鼓勵開發人員使用事件頁面,因為這樣可以節省內存并提高瀏覽器的整體性能。但是,要知道這也是你應該將主邏輯和初始化的地方。 通常,背景頁面/背景腳本 在擴展的其他部分之間扮演橋梁的角色。 在`manifest.json`文件中可以如此定義`background`: ~~~ "background": { "scripts": ["background.js"], "persistent": false/true } ~~~ 正如您可能已經猜到的,如果 `persistent` 屬性是 `false` ,那么您將使用**事件頁面**。否則,您將使用一個持久的后臺頁面。 顧名思義,可以理解為背景頁面腳本,或者直接解釋為后臺腳本。background 用來處理插件本身的一些邏輯,比如插件加載時需要執行的處理,運行中需要統一維護的數據等等,background 只會在插件加載的時候運行一次,你可以在這個過程中讓它綁定一些運行中的事件。 ## Content Script 如果您需要訪問當前頁面的DOM,那么您就需要用到內容腳本 content script。該腳本代碼是在當前web頁面的上下文中運行的,這意味著它將在每次頁面刷新時執行。要添加這樣的腳本,請使用以下語法 ``` "content_scripts": [ { "matches": ["http://*/*", "https://*/*"], "js": ["content.js"] } ] ``` 請記住,`matches`的值決定了您的腳本會對哪個頁面有效。請閱讀有關[匹配模式](https://developer.chrome.com/extensions/match_patterns.html)的更多信息。 content script 跟頁面 page 共用同一份頁面的 dom,也就是說 content script 可以直接去訪問或修改當前頁面的 dom,但是注意了,它們只是共享了 dom 的訪問,js 處理本身卻是在兩個不同的沙盒中運行的,所以并不能互調各自的js代碼。 如下處理是在當前頁面中插入一個div節點: ``` var element = document.body.firstChild; var div = document.createElement("div"); document.body.insertBefore(div, element); ``` 那么在 content script 中能跟 background 交互嗎?當然。首先在 content script 中可以通過`chrome.extension.sendRequest`給 background 發送消息請求,同時可以通過`chrome.extension.onRequest.addListener`來監聽從 background 發送來的消息。 content script 除了跟 background 可以交互,跟 web page 本身也可以有信息交互。一方面 content script 可以直接訪問 page 的 dom,同時還可以通過 dom 的 Event 來跟頁面進行交互。 ## 用戶界面 有幾種方法可以構建你的擴展的 UI。以下是最受歡迎的四種。 ### Browser Action 大多數開發人員使用`browser_action`屬性來構建他們的插件。一旦你設置好了,一個代表你的擴展名的圖標就會被放在地址欄的右邊。然后,用戶可以單擊圖標并打開一個實際上是由您控制的HTML內容的彈出窗口。 ![](https://img.kancloud.cn/69/2d/692d99383555b2936ed6b686bc95042f_471x145.png) `manifest.json`文件中對`browser action`進行配置。 ``` "browser_action": { "default_icon": { "19": "icons/19x19.png", "38": "icons/38x38.png" }, "default_title": "That's the tool tip", "default_popup": "popup.html" } ``` `default_title`是一個小工具提示,當用戶鼠標懸置在您的圖標上時顯示。`default_popup`實際上是在彈出窗口中加載的名為`popup.html`的HTML文件。還有一個徽章,你可以把它放在你的圖標上。您可以在后臺腳本中執行該操作。例如 ~~~ chrome.browserAction.setBadgeText({text: "yeah"}); ~~~ 在`browser action`中通過background對象可以直接調用background中定義的方法或對象,如下所示,假設在`background.js`中定義了`testBG`函數,那么在popup.html中可以這樣訪問: ~~~ var bg = chrome.extension.getBackgroundPage(); bg.testBG(); ~~~ ### Page Action `page_action` 屬性類似于browser action,但是它會在地址欄中顯示圖標,所以一般會跟當前訪問的URL地址進行交互。 ![](https://img.kancloud.cn/4b/fc/4bfc1c96b80b282374fc4057eeb47f85_600x79.png) 有趣的是,您的圖標最初是隱藏的,因此您可以決定何時顯示它。例如,在上面的圖片中,RSS 圖標只有在當前頁面包含了 RSS 提要的鏈接時才會顯示。如果你需要一直看到你的圖標,直接使用 `browser_action` 是很好的 使用`page action`功能,需要在`manifest.json`中定義如下屬性: ``` "page_action": { "default_icon": { "19": "images/icon19.png", "38": "images/icon38.png" }, "default_title": "Google Mail", "default_popup": "popup.html" } ``` 與 browser action 的圖標不同,頁面動作的圖標沒有 badges。 我們可以把對 page aciton 的設置和處理放在 background page 中,從而直接在 background 中通過 `chrome.pageAction` 來設置page action,比如如下代碼實現了當所訪問URL中有 rss 字符串時就顯示page action的 icon 這樣的功能: ``` chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { if (tab.url.indexOf("rss") > -1) { chrome.pageAction.show(tabId); } }); ``` ### DeveloperTools 我經常使用開發者工具,很高興Chrome提供了一種方法來為這些工具添加新的標簽。首先要做的是添加一個HTML頁面,當面板打開時,它將被加載。 ~~~ "devtools_page": "devtools.html" ~~~ 不需要在頁面內放置任何HTML,除了在JavaScript文件的鏈接,這將創建標簽: ~~~ <script src="devtools.js"></script>; ~~~ 然后在 `devtools.js` 文件中包含以下代碼: ```js chrome.devtools.panels.create( "TheNameOfYourExtension", "img/icon16.png", "index.html", function() { } ); ``` 現在,上面的代碼會添加一個新的名為`TheNameOfYourExtension` 的標簽,一旦你點擊它,瀏覽器就會在DeveloperTools里面加載該 `index.html`。 ### Omnibox `omnibox`是在Chrome的地址欄中顯示的關鍵字。例如,如果您將以下屬性添加到您的manifest中: ```js "omnibox": { "keyword" : "yeah" } ``` 然后在 background 腳本中添加以下代碼: ```js chrome.omnibox.onInputChanged.addListener(function(text, suggest) { suggest([ {content: text + " one", description: "the first one"}, {content: text + " number two", description: "the second entry"} ]); }); chrome.omnibox.onInputEntered.addListener(function(text) { alert('You just typed "' + text + '"'); }); ``` 你應該能夠在地址欄里輸入`yeah`。然后你會看到這樣: ![](https://img.kancloud.cn/42/41/4241bd72e93d5e1e6df89fb7b8125433_600x63.png) 按下 tab 鍵會產生以下屏幕: ![](https://img.kancloud.cn/25/0a/250a1976b8c9e16e96975f6331c6f5f2_600x111.png) 當然是使用了 `chrome.omnibox` API,您可以捕獲用戶的輸入并對該輸入作出反應。 ## APIs 你可以在擴展中做很多不同的事情。例如,您可以訪問用戶的書簽或歷史記錄。你可以移動,創建標簽,甚至調整主窗口的大小。我強烈建議查閱[文檔](https://developer.chrome.com/extensions/api_index.html),以便更好地了解如何完成這些任務。 您應該知道的是,并不是所有的 APIs 都可以在擴展的每個部分中使用。例如,您的內容腳本不能訪問`chrome.devtools.panels`或您的開發者工具標簽中的腳本不能讀取頁面的DOM。所以,你肯定想知道為什么有些東西不起作用: ### 消息傳送 正如我上面提到的,您并不總是能夠訪問您想要使用的API。如果是這樣,那么您應該使用消息傳遞。有兩種類型的消息傳遞—— 一次性請求和長時間連接。 #### [兼容性](https://stackoverflow.com/questions/15718066/chrome-runtime-sendmessage-not-working-as-expected) `chrome.runtime.sendMessage / onMessage`(還有`connect`也是相似的)都是在 Chrome 26 開始引入的。 如果你想兼容 Chrome 20 - 25 版本,那么請使用 `chrome.extension.sendMessage`。 最好的兼容 `chrome.runtime` 方法如下示例: ```js if (!chrome.runtime) { // Chrome 20-21 chrome.runtime = chrome.extension; } else if(!chrome.runtime.onMessage) { // Chrome 22-25 chrome.runtime.onMessage = chrome.extension.onMessage; chrome.runtime.sendMessage = chrome.extension.sendMessage; chrome.runtime.onConnect = chrome.extension.onConnect; chrome.runtime.connect = chrome.extension.connect; } ``` #### 一次性請求 這種類型的通信只發生一次。也就是說,你發送一個信息,等待一個回復。例如,您可以在 background 腳本中放置以下代碼: ```js chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { switch(request.type) { case "dom-loaded": alert(request.data.myProperty); break; } return true; }); ``` 然后在你的 content 腳本中使用下面的代碼: ```js window.addEventListener("load", function() { chrome.runtime.sendMessage({ type: "dom-loaded", data: { myProperty: "value" } }); }, true); ``` 這就是如何獲取關于當前頁面DOM的信息并在background 腳本中使用它。如果不這樣 ,background 腳本通常無法訪問這些數據。 #### 長時間連接 如果需要持久的通信通道,請使用這種類型的消息傳遞。在您的 content 腳本中,放置以下代碼: ```js var port = chrome.runtime.connect({name: "my-channel"}); port.postMessage({myProperty: "value"}); port.onMessage.addListener(function(msg) { // do some stuff here }); ``` 然后在background 腳本中,使用這個: ```js chrome.runtime.onConnect.addListener(function(port) { if(port.name == "my-channel"){ port.onMessage.addListener(function(msg) { // do some stuff here }); } }); ``` ### 覆蓋頁面 覆蓋頁面是定制瀏覽器的一種很好的方式。你也可以替代Chrome中的一些默認的頁面。例如,您可以創建自己的歷史頁面。要做到這一點,需要添加以下代碼片段: ```js "chrome_url_overrides" : { "<page to override>;": "custom.html" } ``` `<page to override>`的值可以為:`bookmarks`,`history` 和 `newtab`。創建自己的新的標簽頁是很酷的。 # 一個擴展示例 為了總結這篇文章,我決定創建一個簡單的示例,這樣您就可以更好地理解整個所示圖片。這個示例擴展使用了我上面所描述的大部分內容,只是為當前頁面中的所有`div`設置了一個`#F00`的背景顏色。您可以[下載源代碼](https://github.com/tutsplus/developing-google-chrome-extensions)。 ## Manifest 文件 我們當然還是先從 manifest 文件開始: ```js { "name": "BrowserExtension", "version": "0.0.1", "manifest_version": 2, "description" : "Description ...", "icons": { "16": "icons/16x16.png", "48": "icons/48x48.png", "128": "icons/128x128.png" }, "omnibox": { "keyword" : "yeah" }, "browser_action": { "default_icon": { "19": "icons/19x19.png", "38": "icons/38x38.png" }, "default_title": "That's the tool tip", "default_popup": "browseraction/popup.html" }, "background": { "scripts": ["background.js"], "persistent": false }, "chrome_url_overrides" : { "newtab": "newtab/newtab.html" }, "content_scripts": [{ "matches": ["http://*/*", "https://*/*"], "js": ["content.js"] }], "devtools_page": "devtools/devtools.html" } ``` 請記住,您可以將您的文件組織到文件夾中。另外,請注意該 `version` 屬性。每次你想要把你的擴展上傳到網絡商店時,你都應該更新這個屬性。 ## Background 腳本 ```js // omnibox chrome.omnibox.onInputChanged.addListener(function(text, suggest) { suggest([ {content: "color-divs", description: "Make everything red"} ]); }); chrome.omnibox.onInputEntered.addListener(function(text) { if(text == "color-divs") colorDivs(); }); // listening for an event / one-time requests // coming from the popup chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { switch(request.type) { case "color-divs": colorDivs(); break; } return true; }); // listening for an event / long-lived connections // coming from devtools chrome.runtime.onConnect.addListener(function (port) { port.onMessage.addListener(function (message) { switch(port.name) { case "color-divs-port": colorDivs(); break; } }); }); // send a message to the content script var colorDivs = function() { chrome.tabs.getSelected(null, function(tab){ chrome.tabs.sendMessage(tab.id, {type: "colors-div", color: "#F00"}); // setting a badge chrome.browserAction.setBadgeText({text: "red!"}); }); } ``` 前幾行從 omnibox 中獲得用戶的操作。在此之后,我設置了一個一次性的請求偵聽器,它將接受來自 browser action 圖標的消息。 接下來一個代碼片段是與devtools選項卡進行的長時間連接(這并不是絕對必要的,我只是為了這篇教程才這么做的)。通過使用這些偵聽器,我可以從用戶那里獲得輸入,并將其發送到 content 腳本,其腳本可以訪問DOM元素。這里的關鍵是首先選擇我想要操作的選項卡,然后向它發送一條消息。最后,我在擴展圖標上添加了一個 badge 。 ## Browser Action 從我們的`popup.html`文件開始: ```html // popup.html <script type="text/javascript" src="popup.js"></script> <div style="width:200px"> <button id="button">Color all the divs</button> </div> ``` 然后新建 `popup.js` 文件: ```js // popup.js window.onload = function() { document.getElementById("button").onclick = function() { chrome.runtime.sendMessage({ type: "color-divs" }); } } ``` 彈出框包含一個按鈕,一旦用戶點擊它,它就會向后臺腳本發送一條消息。 ## DeveloperTools ```js window.onload = function() { var port = chrome.runtime.connect({ name: "color-divs-port" }); document.getElementById("button").onclick = function() { port.postMessage({ type: "color-divs"}); } } ``` 對于開發者工具,我們在這里做的幾乎和在彈出窗口中做的一樣,唯一的區別是我使用了一個長時間的連接。 ## Content 腳本 ```js chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { switch(message.type) { case "colors-div": var divs = document.querySelectorAll("div"); if(divs.length === 0) { alert("There are no any divs in the page."); } else { for(var i=0; i&lt;divs.length; i++) { divs[i].style.backgroundColor = message.color; } } break; } }); ``` 這個content 腳本監聽消息,選擇當前頁面上的所有`div`,并更改它們的背景顏色。注意我將監聽器連接到的對象,在 content 腳本中是[`chrome.runtime.onMessage`](https://chajian.baidu.com/developer/extensions/runtime.html#method-sendMessage)。 ## 定制新的標簽頁(`New Tab`) 這個擴展所做的最后一件事是定制`新的`標簽頁。只需將 `newtab` 屬性指向`newtab/newtab.html`文件,我們就可以輕松地做到這一點: ```js "chrome_url_overrides" : { "newtab": "newtab/newtab.html" } ``` 請記住,您不能創建默認的新選項卡頁面的副本。這個特性的想法是添加一個完全不同的功能。以下是谷歌的說法: > 不要試圖模擬默認的新選項卡頁面。創建一個稍微修改過的默認新選項卡頁面的api——包括頂部頁面、最近關閉的頁面、提示、主題背景圖像等等——還不存在。在做到這一點之前,你最好試著去做一些完全不同的事情。 # 調試 為谷歌 Chrome 寫一個擴展并不總是一件容易的事,你可能會遇到一些問題。好處是,您仍然可以使用控制臺輸出變量,以幫助調試。你可以隨意添加`console.log`到您的 background 或 content 腳本。然而,在開發人員工具的上下文中運行的腳本,這不會起作用,在這種情況下,您可能會考慮使用 `alert` 方法,因為它在任何地方都是有效的。 # 總結 在我看來,Chrome是最好的瀏覽器之一。Google的開發人員通過讓我們有能力在HTML、CSS和JavaScript中創建擴展,使得創建擴展變得相對容易。 是的,雖然有一些棘手的部分,但是總的來說,我們還是能夠產生有價值的插件。請記住,本文并沒有涵蓋與開發Chrome擴展相關的所有內容。還有其他一些有用的東西,比如上下文菜單、選項頁面和通知。對于我沒有涉及的主題,請參閱[文檔](https://developer.chrome.com/extensions/)以獲得更詳細的信息。 # 參考 [Developing Google Chrome Extensions](https://code.tutsplus.com/tutorials/developing-google-chrome-extensions--net-33076)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看