前面に書かれたこのブログ記事を断続的に書き上げるのに約 1 か月かかり、完全なデモを慎重に書き上げました。ブログを書くのがいかに大変かは誰もが知っているので、転載する際には必ずソースをそのまま残してください。この記事で取り上げるコードのほとんどは、このデモ (https://github.com/sxei/chrome-plugin-demo) にあります。ダウンロードして直接実行できます。 また、この記事には写真が多く含まれており、写真サーバーの帯域幅が限られています。右下隅のディレクトリスクロール監視は、すべての写真が読み込まれるまで待機してからトリガーされますので、読み込みが完了するまでしばらくお待ちください。 この記事の内容: デモのスクリーンショットをいくつか紹介します。 序文Chromeプラグインとは厳密に言えば、ここで取り上げているのは Chrome プラグインは、ブラウザの機能を強化するために Web テクノロジを使用して開発されたソフトウェアです。これは、HTML、CSS、JS、画像、その他のリソースで構成される .crx サフィックスを持つ圧縮パッケージです。 さらに、これは単なるフロントエンド技術ではありません。Chrome プラグインは、C++ で記述された dll ダイナミック リンク ライブラリと連携して、全画面スクリーンショットなどのいくつかの低レベル機能 (NPAPI) を実装することもできます。 セキュリティ上の理由により、Chrome ブラウザ バージョン 42 以降では NPAPI プラグインがサポートされなくなり、より安全な PPAPI に置き換えられました。 Chrome プラグイン開発を学ぶことの意義は何ですか?ブラウザの機能を強化し、独自の「カスタマイズされた」ブラウザを簡単に作成できます。 Chrome プラグインには、次のような便利な API が多数用意されています。
Firefox プラグインではなく Chrome プラグインを使用するのはなぜですか?
開発とデバッグChrome プラグインには厳密なプロジェクト構造の要件はありません。このディレクトリに プラグイン管理ページには、右上のメニュー -> その他のツール -> 拡張機能から入るか、アドレスバーに chrome://extensions と直接入力してアクセスすることもできます。 プラグインをフォルダー形式で直接読み込むには、 開発中は、コードを変更するとプラグインを再読み込みする必要があります。プラグイン管理ページで コアの紹介マニフェストこれは Chrome プラグインの最も重要かつ不可欠なファイルです。プラグイン関連のすべての設定を構成するために使用され、ルート ディレクトリに配置する必要があります。このうち、 以下は一般的な設定項目の一部です。すべて中国語のコメントが付いています。完全な設定ドキュメントについては、ここをクリックしてください。 { // マニフェストファイルのバージョン。必ず記述する必要があり、2である必要があります。 "マニフェストバージョン": 2, // プラグインの名前 "name": "demo", // プラグインのバージョン "version": "1.0.0", // プラグインの説明 "description": "シンプルな Chrome 拡張機能のデモ", // アイコン、すべてのアイコンに 1 つのサイズを使用するだけで問題ありません "icons": { "16": "img/icon.png", "48": "img/icon.png", "128": "img/icon.png" }, // 常に存在する背景 JS または背景ページ "background": { // 指定方法は 2 つ、JS を指定すると背景ページが自動的に生成されます "page": "background.html" //"スクリプト": ["js/background.js"] }, // ブラウザアイコンの設定は右上隅で、browser_action、page_action、app を選択する必要があります "browser_action": { "default_icon": "img/icon.png", // アイコンがホバーされたときのタイトル、オプション "default_title": "これはサンプルの Chrome プラグインです", "default_popup": "popup.html" }, // 特定のページを開いたときにのみ表示されるアイコン /*"page_action": { "default_icon": "img/icon.png", "default_title": "私はページアクションです", "default_popup": "popup.html" },*/ // ページにJSを直接挿入する必要がある 「コンテンツスクリプト」: [ { //"一致": ["http://*/*", "https://*/*"], // "<all_urls>" はすべてのアドレスに一致することを意味します "matches": ["<all_urls>"], // 複数の JS が順番に挿入されます "js": ["js/jquery-1.8.3.js", "js/content-script.js"], // JS は気軽に挿入できますが、CSS は注意が必要です。注意しないとグローバル スタイルに影響する可能性があります。"css": ["css/custom.css"], // コード挿入の時間です。オプションの値: "document_start"、"document_end"、または "document_idle"。最後のものはページがアイドル状態であることを意味します。デフォルトは document_idle です。 "run_at": "ドキュメントの開始" }, // これは、content-script が複数のルールで設定できることを示すためだけのものです { 「一致」: ["*://*/*.png", "*://*/*.jpg", "*://*/*.gif", "*://*/*.bmp"], "js": ["js/show-image-content-size.js"] } ]、 // 権限アプリケーション「permissions」: [ "contextMenus", // 右クリックメニュー "tabs", // タグ "notifications", // 通知 "webRequest", // Web リクエスト "webRequestBlocking", "storage", // プラグインのローカルストレージ "http://*/*", // executeScript または insertCSS 経由でアクセスできる Web サイト "https://*/*" // executeScript または insertCSS 経由でアクセスできる Web サイト ], // 通常のページから直接アクセスできるプラグイン リソースのリスト。設定されていない場合は直接アクセスできません "web_accessible_resources": ["js/inject.js"], // プラグインのホームページ、これは非常に重要です。この無料の広告スペースを無駄にしないでください "homepage_url": "https://www.baidu.com", // ブラウザのデフォルト ページ「chrome_url_overrides」を上書きします: { // ブラウザのデフォルトの新規タブページを上書きする "newtab": "newtab.html" }, // Chrome 40 より前のプラグイン設定ページの書き方 "options_page": "options.html", // Chrome 40 以降でプラグイン設定ページを書く方法。両方書いた場合、新しいバージョンの Chrome は後者の "options_ui" のみを認識します。 { "ページ": "options.html", // デフォルトのスタイルをいくつか追加します。"chrome_style": true を使用することをお勧めします。 }, // アドレスバーにキーワードを登録して検索候補を表示します。設定できるキーワードは 1 つだけです "omnibox": { "keyword" : "go" }, // デフォルト言語 "default_locale": "zh_CN", // devtools ページエントリ。JS ファイルではなく HTML ファイルのみを指すことができることに注意してください "devtools_page": "devtools.html" } コンテンツ スクリプトいわゆるコンテンツ スクリプトは、実際には Chrome プラグインのページへのスクリプト挿入の一種です (スクリプトと呼ばれていますが、実際には CSS を含めることができます)。 構成例: { // ページにJSを直接挿入する必要がある 「コンテンツスクリプト」: [ { //"一致": ["http://*/*", "https://*/*"], // "<all_urls>" はすべてのアドレスに一致することを意味します "matches": ["<all_urls>"], // 複数の JS が順番に挿入されます "js": ["js/jquery-1.8.3.js", "js/content-script.js"], // JS は気軽に挿入できますが、CSS は注意が必要です。注意しないとグローバル スタイルに影響する可能性があります。"css": ["css/custom.css"], // コード挿入の時間です。オプションの値: "document_start"、"document_end"、または "document_idle"。最後のものはページがアイドル状態であることを意味します。デフォルトは document_idle です。 "run_at": "ドキュメントの開始" } ]、 } document.addEventListener('DOMContentLoaded', 関数() { console.log('処刑されました!'); });
実際、これを見て悲観的にならないでください。ほとんどの場合、これらの API で十分です。他の API を本当に呼び出す必要がある場合は、通信を使用してバックグラウンドで呼び出しを行うこともできます (通信については後で詳しく説明します)。 Chrome プラグインは、このような強力な JS インジェクション機能を提供します。あとは想像力を駆使してブラウザを操作するだけです。 背景バックグラウンド(このように翻訳しましょう)は、プラグイン内のすべての種類のページの中で最も長いライフサイクルを持つ永続的なページです。ブラウザを開くと開き、ブラウザを閉じると閉じるので、常に実行する必要があり、起動時に実行されるグローバルコードは、通常、バックグラウンドに配置されます。 Background は非常に高い権限を持ち、ほぼすべての Chrome 拡張機能 API (devtools を除く) を呼び出すことができ、制限なくドメインをまたいであらゆる Web サイトにアクセスできます。つまり、相手側が テストの結果、バックグラウンドだけでなく、 設定では、 { // 常に存在する背景 JS または背景ページ "background": { // 指定方法は 2 つ、JS を指定すると背景ページが自動的に生成されます "page": "background.html" //"スクリプト": ["js/background.js"] }, } イベントページここでイベントページについて紹介したいと思います。イベントページとは何でしょうか?バックグラウンドのライフサイクルが長すぎるため、バックグラウンドを長時間マウントするとパフォーマンスに影響する可能性があるため、Google は { "背景": { "スクリプト": ["イベントページ.js"], 「永続的」: false }, } そのライフサイクルは、必要なときにロードされ、アイドル状態のときに閉じられることです。必要なときとはどういう意味ですか?たとえば、最初のインストール、プラグインの更新、コンテンツ スクリプトによるメッセージの送信などです。 設定ファイルの変更に加えて、コードにもいくつかの小さな変更があります。簡単に確認する必要があります。一般的に言えば、バックグラウンドはパフォーマンスをあまり消費しません。 ポップアップ
設定方法: { 「ブラウザアクション」: { "default_icon": "img/icon.png", // アイコンがホバーされたときのタイトル、オプション "default_title": "これはサンプルの Chrome プラグインです", "default_popup": "popup.html" } } ポップアップはアイコンをクリックすると開き、フォーカスが外れるとすぐに閉じられるため、ポップアップ ページのライフ サイクルは一般に非常に短いことに注意することが重要です。長時間実行する必要があるコードは、ポップアップ内に記述しないでください。 権限の面では、バックグラウンドと非常に似ています。両者の最大の違いは、ライフサイクルの違いです。ポップアップでは、 挿入されたスクリプトここでの これは、 // ページにJSを挿入する 関数 injectCustomJs(jsPath) { jsPath = jsPath || 'js/inject.js'; var temp = document.createElement('script'); temp.setAttribute('type', 'text/javascript'); // 取得したアドレスは次のようになります: chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js temp.src = chrome.extension.getURL(jsPath); temp.onload = 関数() { // ページ上で見栄えが悪いので、実行後に削除します。this.parentNode.removeChild(this); }; document.head.appendChild(temp); } それだけだと思いますか?実行すると、次のエラーが表示されます。
つまり、Web 上のプラグインのリソースに直接アクセスしたい場合は、明示的に宣言する必要があります。構成ファイルに次の内容を追加します。 { // 通常のページから直接アクセスできるプラグイン リソースのリスト。設定されていない場合は直接アクセスできません "web_accessible_resources": ["js/inject.js"], } ホームページURL開発者またはプラグインのホームページ設定は、通常、次の 2 つの場所に表示されます。 Chromeプラグインの8つの表示モードbrowserAction (ブラウザの右上隅) 構成例は次のとおりです。 「ブラウザアクション」: { "default_icon": "img/icon.png", "default_title": "これはサンプルの Chrome プラグインです", "default_popup": "popup.html" } アイコン
ツールチップ
バッジ
chrome.browserAction.setBadgeText({text: 'new'}); chrome.browserAction.setBadgeBackgroundColor({color: [255, 0, 0, 255]}); 効果: pageAction (アドレスバーの右側) Chrome の以前のバージョンでは、pageAction がアドレス バーの右端に配置されていたことに注意してください。左クリックするとポップアップが表示され、右クリックするとデフォルトのオプション メニューが表示されます。 Chrome の新バージョンでは、この戦略が変更されました。PageAction は通常の browserAction と同様にブラウザの右上隅に配置されますが、点灯していないときは灰色で、点灯しているときはカラフルです。灰色のときは、左クリックでも右クリックでもオプションがポップアップ表示されます。 どのバージョンから変更が始まったのか詳しくは調べていませんが、v50.0 では前者のままで、v58.0 で後者に変更されたことはわかっています。 調整後は、
例(アイコンはBaiduを開いたときにのみ表示されます): // マニフェスト.json { 「ページアクション」: { "default_icon": "img/icon.png", "default_title": "私はページアクションです", "default_popup": "popup.html" }, "権限": ["宣言コンテンツ"] } // 背景.js chrome.runtime.onInstalled.addListener(function(){ chrome.declarativeContent.onPageChanged.removeRules(未定義、関数(){ chrome.declarativeContent.onPageChanged.addRules([ { 条件: [ // Baidu が開かれたときのみ pageAction が表示されます 新しい chrome.declarativeContent.PageStateMatcher({pageUrl: {urlContains: 'baidu.com'}}) ]、 アクション: [新しい chrome.declarativeContent.ShowPageAction()] } ]); }); }); 効果画像: 右クリックメニューChrome プラグインを開発すると、主に 最も単純な右クリックメニューの例// マニフェスト.json {"権限": ["コンテキストメニュー"]} // 背景.js chrome.contextMenus.create({ タイトル: 「右クリックメニューのテスト」 onclick: function(){alert('右クリックメニューをクリックしました!');} }); 効果: 右クリックでBaidu検索を追加// マニフェスト.json {"権限": ["コンテキストメニュー", "タブ"]} // 背景.js chrome.contextMenus.create({ title: 'Baidu で検索: %s', // %s は選択されたテキストを示します contexts: ['selection'], // この右クリック メニューはテキストが選択されている場合にのみ表示されます onclick: function(params) { // location は背景に属するウィンドウ オブジェクトであるため、location.href は使用できません。chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(params.selectionText)}); } }); 効果は以下のとおりです。 構文ここでは一般的なものをいくつか紹介します。完全な API については、https://developer.chrome.com/extensions/contextMenus をご覧ください。 chrome.contextMenus.create({ type: 'normal', // タイプ、オプション: ["normal", "checkbox", "radio", "separator"]、デフォルトは normal title: 'メニュー名', // 表示されるテキスト。タイプが「セパレータ」でない限り、このパラメータは必須です。タイプが「選択」の場合、%s を使用して選択されたテキストを表示できます。コンテキスト: ['page'], // コンテキスト。オプション: ["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"], デフォルト ページ onclick: function(){}, // クリック時にトリガーされるメソッド parentId: 1, // 右クリック メニュー項目の親メニュー項目 ID。親メニュー項目を指定すると、このメニュー項目は親メニュー項目のサブメニューになります。 documentUrlPatterns: 'https://*.baidu.com/*' // 特定のページでのみこの右クリック メニューを表示します}); // メニュー項目を削除します。chrome.contextMenus.remove(menuItemId); // すべてのカスタム右クリックメニューを削除します。chrome.contextMenus.removeAll(); // メニュー項目を更新します chrome.contextMenus.update(menuItemId, updateProperties); オーバーライド(特定のページをオーバーライドする) 拡張機能は次のページを置き換えることができます:
知らせ:
以下のスクリーンショットは、デフォルトの新しいタブ ページと拡張機能によって置き換えられた新しいタブ ページを示しています。 コード (プラグインは 1 つのデフォルト ページのみを置き換えることができることに注意してください。以下はデモンストレーション用です): 「chrome_url_overrides」: { "新しいタブ": "新しいタブ.html", "履歴": "history.html", "ブックマーク": "bookmarks.html" } 開発ツール予熱Vue を使用したことがある人なら、このタイプのプラグインを見たことがあるはずです。 はい、Chrome では、主に次の方法でプラグインが開発者ツール (devtools) を改ざんすることを許可しています。
まず、カスタム パネル (現在のページで jQuery が使用されているかどうかを判断するため) の 2 つの簡単なデモ スクリーンショットを見てみましょう。 サイドバーをカスタマイズします(現在のページのすべての画像を取得します): devtools拡張機能の紹介ホームページ: https://developer.chrome.com/extensions/devtools 公式の写真はこちらです: 開発者ツール ウィンドウが開かれるたびに、devtools ページのインスタンスが作成されます。F12 ウィンドウが閉じられるとページも閉じられるため、devtools ページのライフ サイクルは devtools ウィンドウと一致します。 devtools ページでは、一連の固有の
ほとんどの拡張 API は 例: devtools拡張機能の作成まず、開発者ツール用のプラグインを開発するには、マニフェスト ファイルで以下を宣言する必要があります。 { // HTML ファイルのみを指定でき、JS ファイルを指定することはできません "devtools_page": "devtools.html" } この <!DOCTYPE html> <html> <ヘッド></ヘッド> <本文> <script type="text/javascript" src="js/devtools.js"></script> </本文> </html> 実際のコードは devtools.js のコードを見てみましょう。 // カスタム パネルを作成します。同じプラグインで複数のカスタム パネルを作成できます。// パラメータは、パネルのタイトル、アイコン (実際には表示する場所はありません)、読み込むページ、読み込み成功後のコールバックです。chrome.devtools.panels.create('MyPanel', 'img/icon.png', 'mypanel.html', function(panel) { console.log('カスタム パネルが正常に作成されました!'); // このログは通常表示されないことに注意してください}); // カスタムサイドバーを作成する chrome.devtools.panels.elements.createSidebarPane("Images", function(sidebar) { // sidebar.setPage('../sidebar.html'); // 読み込むページを指定します sidebar.setExpression('document.querySelectorAll("img")', 'All Images'); // 式で指定します //sidebar.setObject({aaa: 111, bbb: 'Hello World!'}); // オブジェクトの表示を直接設定します}); setPageの効果: 次のスクリーンショットはコードを示しています。 // jQuery を検出 document.getElementById('check_jquery').addEventListener('click', 関数() { // 検査されたページのDOMにアクセスするにはinspectedWindowを使用する必要があります // 簡単な例: チェック対象のページが jQuery を使用しているかどうかを確認します chrome.devtools.inspectedWindow.eval("jQuery.fn.jquery", 関数(結果、isException) { var html = ''; if (isException) html = '現在のページでは jQuery を使用していません。 '; else html = '現在のページは jQuery を使用しており、バージョンは次のとおりです:' + result; アラート(html); }); }); // リソースを開く document.getElementById('open_resource').addEventListener('click', function() { chrome.devtools.inspectedWindow.eval("window.location.href", 関数(結果、isException) { chrome.devtools.panels.openResource(結果、20、関数() { console.log('リソースが正常に開かれました!'); }); }); }); // 要素を確認する document.getElementById('test_inspect').addEventListener('click', function() { chrome.devtools.inspectedWindow.eval("inspect(document.images[0])", function(result, isException){}); }); // すべてのリソースを取得する document.getElementById('get_all_resources').addEventListener('click', function() { chrome.devtools.inspectedWindow.getResources(関数(リソース) { アラート(JSON.stringify(リソース)); }); }); デバッグのヒントdevtools ページでコードを変更する場合は、chrome://extensions ページで devtools 自体は開発者ツール ページであるため、直接デバッグする方法はほとんどありません。 オプション(オプションページ)いわゆる Chrome 40 より前では、オプション ページは他の通常のページと変わりませんでしたが、Chrome 40 以降ではいくつか変更がありました。 まず、オプションの古いバージョンを見てみましょう。 { // Chrome 40 より前のプラグイン設定ページの書き方 "options_page": "options.html", } このページの内容はあなた次第です。設定後、プラグイン管理ページに 効果: optionsV2 の新しいバージョンを見てみましょう。 { 「オプション_ui」: { "ページ": "options.html", // デフォルトのスタイルをいくつか追加します。"chrome_style": true を使用することをお勧めします。 }, } 背が高くて雄大に見えませんか? いくつかの注意事項:
オムニボックス
キーワードを登録してプラグイン独自の検索候補インターフェースをトリガーすると、それを使って好きなことを実行できるようになります。 まず、設定ファイルは次のようになります。 { // アドレスバーにキーワードを登録して検索候補を表示します。設定できるキーワードは 1 つだけです "omnibox": { "keyword" : "go" }, } 次に、 // オムニボックスデモ chrome.omnibox.onInputChanged.addListener((text, suggest) => { console.log('入力変更: ' + テキスト); if(!text) 戻り値: if(text == '美しさ') { 提案する([ {content: '中国' + text, description: '「中国の美女」をお探しですか? '}, {content: '日本' + text, description: '「日本の美人」をお探しですか? '}, {content: 'タイ' + テキスト、説明: '「タイの美女またはレディーボーイ」をお探しですか? '}, {content: '韩国' + text, description: '「韓国美人」をお探しですか? '} ]); } そうでない場合(テキスト == 'Weibo') { 提案する([ {コンテンツ: 'Sina' + テキスト、説明: 'Sina' + テキスト}, {コンテンツ: 'Tencent' + テキスト、説明: 'Tencent' + テキスト}, {コンテンツ: 'Sohu' + テキスト、説明: '検索' + テキスト}, ]); } それ以外 { 提案する([ {コンテンツ: 'Baidu 検索' + テキスト、説明: 'Baidu 検索' + テキスト}, {コンテンツ: 'Google 検索' + テキスト、説明: 'Google 検索' + テキスト}, ]); } }); // ユーザーがキーワード候補を受け取ったときにトリガーされます chrome.omnibox.onInputEntered.addListener((text) => { console.log('入力内容: ' + テキスト); if(!text) 戻り値: var href = ''; if(text.endsWith('美女')) href = 'http://image.baidu.com/search/index?tn=baiduimage&ie=utf-8&word=' + text; そうでない場合は、text.startsWith('Baidu Search')) href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text.replace('Baidu Search', ''); そうでない場合、if(text.startsWith('Google 検索')) href = 'https://www.google.com.tw/search?q=' + text.replace('Google 検索', ''); そうでない場合は、href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + テキスト; オープンUrlCurrentTab(href); }); // 現在のタブIDを取得する 関数 getCurrentTabId(コールバック) { chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { if (コールバック) callback (tabs.length ? tabs[0].id: null); }); } //現在のタブでリンクを開く function openUrlCurrentTab(url) { 現在のタブIDを取得します(タブID => { chrome.tabs.update(タブID、{url: url}); }) } デスクトップ通知Chromeは、 バックグラウンドJSでは、 最も単純な通知: コード: Chrome.notifications.create(null、{ タイプ: 'Basic'、 iconurl: 'img/icon.png'、 タイトル:「これはタイトル」、 メッセージ:「カスタム右クリックメニューをクリックしました! ' }); 通知スタイルは非常にリッチな場合があります: これは詳細に研究されていません。必要に応じて公式のドキュメントを読むことができます。 5種類のJSの比較ChromeプラグインJSは、主にこれらの5つのカテゴリに分けることができます: 許可の比較
デバッグ方法の比較
メッセージ通信メッセージングホームページ:https://developer.chrome.com/extensions/messaging 以前には、Chromeプラグインに5種類のJSを導入しましたが、どのように互いに通信しますか?まずシステムの概要を示してから、カテゴリを詳細に説明しましょう。あなたが知る必要があるのは、ポップアップと背景は、同じアクセス可能なAPI、同じ通信メカニズム、そしてドメインを横断できるため、実際にはほぼ同じものと見なすことができるということです。 相互コミュニケーションの概要注:
7.2ポップアップと背景ポップアップは、バックグラウンドでJSメソッドを直接呼び出すか、背景のDOMに直接アクセスできます。 // background.js 関数テスト() { アラート( '私は背景です!'); } // popup.js var bg = chrome.extension.getBackGroundPage(); bg.test(); 小さなエピソードでは、ポップアップが長い間検索した後、JSを積極的にチェックしていない場合、エラーメッセージを表示しないことがわかりました。 var views = chrome.extension.getViews({type: 'popup'}); if(views.length> 0){ console.log(views [0] .location.href); } ポップアップまたはBGは、メッセージをコンテンツに積極的に送信します background.jsまたはpopup.js: 関数sendmessagetocontentscript(メッセージ、コールバック) { Chrome.tabs.query({active:true、currentWindow:true}、function(tabs) { Chrome.tabs.sendmessage(tabs [0] .id、message、function(response) { if(callback)callback(response); }); }); } sendmessagetocontentscript({cmd: 'test'、value: 'hello、impopup!'}、function(response) { console.log( 'コンテンツからの返信:'+response); }); Chrome.runtime.onmessage.addlistener(function(request、sender、sendResponse) { // console.log(sender.tab? "from a content script:" + sender.tab.url: "from the Extension"); if(request.cmd == 'test')alert(request.value); sendResponse( '私はあなたのメッセージを受け取りました!'); }); 両当事者間の通信は、JSON文字列ではなくJSONオブジェクトを直接送信するため、解析する必要はありません。これは非常に便利です(もちろん、文字列を直接送信することもできます)。 インターネット上のいくつかの古いコードは ContentScriptは、積極的にメッセージをバックグラウンドに送信しますcontent-script.js: Chrome.runtime.sendmessage({greeting: 'こんにちは、コンテンツスクリプト、バックグラウンドにメッセージを送信します!'}、function(response){ console.log( 'バックグラウンドから返信を受け取りました:' + response); }); background.jsまたはpopup.js: // contentscript chrome.runtime.onmessage.addlistener(function(request、sender、sendResponse)からメッセージを聞く { console.log( 'contentscriptからメッセージを受信:'); console.log(request、sender、sendResponse); sendResponse( '私はバックエンドです、私はあなたのメッセージを受け取りました:' + json.stringify(request)); }); 注記:
挿入されたスクリプトとコンテンツスクリプトページ内の
最初の方法(推奨): window.postmessage({"test": 'hello!'}、 '*'); コンテンツスクリプト: window.addeventlistener( "message"、function(e) { console.log(e.data); }、 間違い); 2番目の方法: var customevent = document.createevent( 'event'); Customevent.initevent( 'mycustomevent'、true、true); 関数firecustomevent(data){ hiddendiv = document.getElementById( 'mycustomeventdiv'); hiddendiv.innertext = data hiddendiv.dispatchevent(Customevent); } firecustomevent( 'こんにちは、私は普通のjs!'); var hiddendiv = document.getElementById( 'mycustomeventdiv'); if(!hiddendiv){ hiddendiv = document.createelement( 'div'); hiddendiv.style.display = 'none'; document.body.appendchild(hiddendiv); } hiddendiv.addeventlistener( 'mycustomevent'、function(){ var eventData = document.getElementById( 'mycustomeventdiv')。innertext; console.log( 'カスタムイベントメッセージ受信:' + eventData); }); 長くて短い接続実際、それは上記で言及されているので、ここで別々に説明します。 Chromeプラグインには2つの通信方法があり、1つは短い接続( 短い接続 短い接続については上記のコード例がすでにありますので、ここに長い接続があります。 popup.js: getCurrentTabid((tabid)=> { var port = chrome.tabs.connect(tabid、{name: 'test-connect'}); port.postmessage({question: 'you re you?'}); port.onmessage.addlistener(function(msg){ alert( '受信メッセージ:'+msg.answer); if(msg.answer && msg.answer.startswith( 'i')) { port.postmessage({question: 'ああ、それはあなたです!'}); } }); }); content-script.js: //長い接続を聞くChrome.runtime.onconnect.AddListener(function(port){ console.log(port); if(port.name == 'test-connect'){ port.onmessage.addlistener(function(msg){ console.log( 'receive long connection message:'、msg); if(msg.question == 'あなたは誰ですか?')port.postmessage({answer: 'i are your pad!'}); }); } }); その他のサプリメントJSを動的に注入または実行しますページDOMに 例 { 「名前」:「ダイナミックJSインジェクションデモ」、 ... 「許可」:[ 「タブ」、「http://*/*"、" https://*/*" ]、 ... } JS: // js code chrome.tabs.executecript(tabid、{code: 'document.body.style.backgroundcolor = "red"'}); // js file chrome.tabs.executecript(tabid、{file: 'some-script.js'})を動的に実行します。 CSSを動的に注入します例 { 「名前」:「ダイナミックCSSインジェクションデモ」、 ... 「許可」:[ 「タブ」、「http://*/*"、" https://*/*" ]、 ... } JSコード: // cssコード、todo、chrome.tabs.insertcss(tabid、{code: 'xxx'}); // cssファイルchrome.tabs.insertcss(tabid、{file: 'some-style.css'})を動的に実行します。 現在のウィンドウIDを取得しますChrome.windows.getCurrent(function(currentWindow) { console.log( '現在のウィンドウID:' + currentWindow.id); }); 現在のタブIDを取得します通常、2つの方法があります。 //現在のタブIDを取得します 関数getCurrentTabid(コールバック) { Chrome.tabs.query({active:true、currentWindow:true}、function(tabs) { if(callback)callback(tabs.length?tabs [0] .id:null); }); } 現在のタブIDを取得する別の方法はほとんどの場合類似しており、数回しか異なります(たとえば、ウィンドウが最小化されている場合) //現在のタブIDを取得します 関数getCurrentTabid2() { Chrome.windows.getCurrent(function(currentWindow) { Chrome.tabs.query({active:true、windowid:currentWindow.id}、function(tabs) { if(callback)callback(tabs.length?tabs [0] .id:null); }); }); } ローカルストレージ通常のローカル
//最初のパラメーターを読み取ります。 console.log(items.color、items.age); }); // data chrome.storage.sync.set({color: 'blue'}、function(){ console.log( '正常に保存!'); }); WebRequest WebRequestシリーズAPIを通じて、HTTPリクエスト //manifest.json { //許可アプリケーション「許可」: [ 「WebRequest」、// Web要求「WebRequestBlocking」、// Web要求「ストレージ」、//プラグインローカルストレージ "http://*/*"、// executescriptまたはinsertcss "https://*/*" // executescriptまたはinsertcss]を介してアクセスできるウェブサイトを介してアクセスできるWebサイト } // background.js // Image var Showimageを表示するかどうか。 Chrome.storage.sync.get({showimage:true}、function(items){ showimage = items.showimage; }); // webリクエストリスニング、最後のパラメーターはブロッキングを表し、許可を個別に宣言する必要があります:webrequestblocking Chrome.webrequest.onbeforerequest.addlistener(詳細=> { //キャンセルとは、(!showimage && details.type == 'image')return {cancel:true}; //簡単なオーディオとビデオの検出//ほとんどのWebサイトビデオタイプはメディアではなく、ビデオはダウンロードから保護されているため、これはデモンストレーション効果のためだけで、実用的な意味はありません(details.type == 'Media'){ Chrome.notifications.create(null、{ タイプ: 'Basic'、 iconurl: 'img/icon.png'、 タイトル:「オーディオとビデオが検出された」、 メッセージ: 'オーディオとビデオアドレス:' + details.url、 }); } }、{urls:["<all_urls>"]}、["ブロッキング"]); 国際化プラグインのルートディレクトリに { 「PlagindESC」:{"メッセージ":「シンプルなクロム拡張デモ "}、 「Helloworld」:{"メッセージ":「Hello World! "} } { 「PlagindESC」:{"メッセージ":「シンプルなクロムプラグインデモ "}、 「Helloworld」:{"メッセージ":「こんにちは、世界! "} } { 「説明」: "__msg_plugindesc__"、 //デフォルト言語 "default_locale": "zh_cn"、 } JSでは、 テスト中に、次のような 英語効果: 中国の効果: APIサマリー最も一般的に使用されるAPIシリーズの一部:
概要を経験しますインストールされているプラグインパスを表示しますインストールされているプラグインソースパス: プラグインのIDを表示する方法は? Chrome://拡張機能を入力し、開発者モードをフックして表示します。 バックグラウンドエラーレポートに特に注意してください多くの場合、あなたのコードは不可解に失敗し、それを検索した後、それが特定の場所で誤って書かれていることがわかります。 ポップアップページが閉じるのを防ぐ方法ポップアップページの要素を確認すると、ポップアップを閉じることができません。この方法は、場合によっては実用的です! インラインJavaScriptの実行はサポートされていませんつまり、HTMLでJSを直接書くことをサポートしていません。たとえば <入力ID = "btn" type = "button" value = "favorites" onclick = "test()"/> エラーは次のとおりです:
解決策は、イベントをJSで結合することです。 $( '#btn')。 さらに、aタグの場合、 これを書く場合: <a href = "JavaScript :; エラーは次のとおりです:
CSSを注入するときは注意してください
私がこれを強調する理由は、これによってもたらされた問題が非常に隠されており、特定のWebページを書くのが簡単ではないかもしれません。その後、あなたはそれがプラグインのスタイルのためであることを知る前に、それを長い間検索して検索するために一生懸命働きました! パッケージングとパブリッシングパッケージ化すると、プラグイン管理ページに直接パッケージボタンがあります。 次に、Google App Storeに公開する場合は、 参照する公式情報公式の文書を見ることをお勧めします。 Chromeプラグインの公式ドキュメントホームページ 公式クロムプラグインの例 マニフェストマニフェストファイル 権限権限 Chrome.xxx.apiドキュメントファジーマッチングルールの構文の詳細な説明 サードパーティの情報一部の中国の材料は特にお勧めしません: 360安全なブラウザ開発ドキュメント 360スピードブラウザ Chrome Extension Developmentドキュメント Chromeは、Geekシリーズブログの開発を拡大します 添付写真添付画像:Chrome HD PNG形式のロゴ: 上記は、Chromeプラグイン(拡張)開発ガイドの詳細なコンテンツです。123WordPress.comの他の関連記事に注意してください。 以下もご興味があるかもしれません:
|
<<: CentOS 7にMySQLをインストールする詳細な手順
>>: Linux ディスク クォータ管理のグラフィカルな例
Web デザインは、個人の好みや Web ページの内容に応じて、デザインのレイアウトが常に変化します...
ページの自動スクロール効果は JavaScript で実現できますが、今日偶然、JS 制御なしでさま...
目次1. 配列を結合する2. 配列をマージする(最初に) 3. 配列の複製4. 構造化分解割り当て5...
<textarea></textarea> は、複数行を入力できるテキスト ...
上の記事で、SWFObject V1.5 の使い方の紹介は一旦終了です。これから、SWFObject...
MySQL 4.x 以降では、全文検索 MATCH ... AGAINST モード (大文字と小文字...
これはかなり前に書かれた記事です。今となっては、その中の考え方は学ぶ価値があるように思えます。jb5...
JDKダウンロードアドレス: http://www.oracle.com/technetwork/j...
目次序文アドバンテージ:欠点: 1. レスポンシブな使用効果2. ステータスが同期されていないRea...
取引特性1. アトミック性: トランザクションの開始後、すべての操作が完了するか、まったく実行されな...
接続ツールを開きます。私はMobaXterm_Personal_12.1を使用します(公式サイトのダ...
目次0x0 はじめに0x1 RBAC 実装0x2 クレームベースの承認0x3 統合 CASL 0x4...
グラデーションの背景色を作成するときは、 linear-gradient() 関数を使用して線形グラ...
丁寧に掃除を始めましょう!未使用ボリュームの一覧docker ボリューム ls -qf dangli...
エラーメッセージ:エラー 1862 (HY000): パスワードの有効期限が切れています。ログインす...