[解決済み] Chrome Extension コンテンツスクリプトからpopup.htmlにデータを送信する方法
質問
私はこのことが多くの投稿で質問されていることを知っていますが、正直なところ、私はそれらを得ることはありません。私はJavaScript、Chrome Extensions、およびすべてのものに新しいですが、私はこのクラスの課題があります。 私はクロスドメインリクエストを使用して任意のページ上のDOMオブジェクトをカウントするプラグインを作る必要があります。 私はこれまで、Chrome Extension APIを使用してこれを達成することができました。 今問題なのは、contentScript.jsファイルからpopup.htmlページにデータを表示する必要があることです。 ドキュメントを読んでみましたが、クロームのメッセージングを行う方法を理解することができません。
以下はこれまでのコードです。
manifest.json
{
"manifest_version":2,
"name":"Dom Reader",
"description":"Counts Dom Objects",
"version":"1.0",
"page_action": {
"default_icon":"icon.png",
"default_title":"Dom Reader",
"default_popup":"popup.html"
},
"background":{
"scripts":["eventPage.js"],
"persistent":false
},
"content_scripts":[
{
"matches":["http://pluralsight.com/training/Courses/*", "http://pluralsight.com/training/Authors/Details/*", "https://www.youtube.com/user/*", "https://sites.google.com/site/*", "http://127.0.0.1:3667/popup.html"],
"js":["domReader_cs.js","jquery-1.10.2.js"]
//"css":["pluralsight_cs.css"]
}
],
"permissions":[
"tabs",
"http://pluralsight.com/*",
"http://youtube.com/*",
"https://sites.google.com/*",
"http://127.0.0.1:3667/*"
]
popup.html
<!doctype html>
<html>
<title> Dom Reader </title>
<script src="jquery-1.10.2.js" type="text/javascript"></script>
<script src="popup.js" type="text/javascript"></script>
<body>
<H1> Dom Reader </H1>
<input type="submit" id="readDom" value="Read DOM Objects" />
<div id="domInfo">
</div>
</body>
</html>
イベントページ.js
var value1,value2,value3;
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "show") {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.pageAction.show(tabs[0].id);
});
}
value1 = request.tElements;
});
popup.js
$(function (){
$('#readDom').click(function(){
chrome.tabs.query({active: true, currentWindow: true}, function (tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "readDom"});
});
});
});
コンテンツスクリプト
var totalElements;
var inputFields;
var buttonElement;
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
if(request.action == "readDom"){
totalElements = $("*").length;
inputFields = $("input").length;
buttonElement = $("button").length;
}
})
chrome.runtime.sendMessage({
action: "show",
tElements: totalElements,
Ifields: inputFields,
bElements: buttonElement
});
どんな助けでも感謝します、そして私がした無能を避けてください :)
どのように解決するのですか?
あなたは間違いなく正しい方向に向かっていますが (そして実際にはかなり終わりに近づいています)、あなたのコードにはいくつかの (imo) 悪い習慣があります (たとえば、このようなつまらないタスクのためにライブラリ (jquery) 全体を注入する、不要なパーミッションを宣言する、API メソッドの過剰な呼び出しを行うなどです)。
私はあなたのコードを自分でテストしませんでしたが、簡単な概要から、以下を修正することで動作するソリューションが得られると信じています (最適にはとても近くないですが)。
- で manifest.json : コンテンツスクリプトの順序を変更し、jqueryを先にします。によると 関連文書によると :
"js" [...] 一致するページに注入されるJavaScriptファイルのリストです。これらは注入される で表示されます。 で注入されます。
(強調)
-
で
コンテンツスクリプト.js
: を移動する。
chrome.runtime.sendMessage({...})
ブロック
内部
その
onMessage
リスナーのコールバックです。
とはいえ、私が提案するアプローチは以下のとおりです。
制御フロー。
- コンテンツスクリプトは、いくつかの基準に一致する各ページに注入されます。
- 注入されると、コンテンツスクリプトはイベントページ (別名、非永続的なバックグラウンドページ) にメッセージを送信し、イベントページはタブにページアクションをアタッチします。
- ページアクションのポップアップがロードされるとすぐに、コンテンツスクリプトにメッセージを送信し、必要な情報を要求します。
- コンテンツスクリプトはリクエストを処理し、ページアクションポップアップが情報を表示できるように応答します。
ディレクトリ構造。
root-directory/
|__img
|__icon19.png
|__icon38.png
|__manifest.json
|__background.js
|__content.js
|__popup.js
|__popup.html
manifest.json。
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"offline_enabled": true,
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["*://*.stackoverflow.com/*"],
"js": ["content.js"],
"run_at": "document_idle",
"all_frames": false
}],
"page_action": {
"default_title": "Test Extension",
//"default_icon": {
// "19": "img/icon19.png",
// "38": "img/icon38.png"
//},
"default_popup": "popup.html"
}
// No special permissions required...
//"permissions": []
}
background.js:
chrome.runtime.onMessage.addListener((msg, sender) => {
// First, validate the message's structure.
if ((msg.from === 'content') && (msg.subject === 'showPageAction')) {
// Enable the page-action for the requesting tab.
chrome.pageAction.show(sender.tab.id);
}
});
content.js:
// Inform the background page that
// this tab should have a page-action.
chrome.runtime.sendMessage({
from: 'content',
subject: 'showPageAction',
});
// Listen for messages from the popup.
chrome.runtime.onMessage.addListener((msg, sender, response) => {
// First, validate the message's structure.
if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
// Collect the necessary data.
// (For your specific requirements `document.querySelectorAll(...)`
// should be equivalent to jquery's `$(...)`.)
var domInfo = {
total: document.querySelectorAll('*').length,
inputs: document.querySelectorAll('input').length,
buttons: document.querySelectorAll('button').length,
};
// Directly respond to the sender (popup),
// through the specified callback.
response(domInfo);
}
});
popup.js。
// Update the relevant fields with the new data.
const setDOMInfo = info => {
document.getElementById('total').textContent = info.total;
document.getElementById('inputs').textContent = info.inputs;
document.getElementById('buttons').textContent = info.buttons;
};
// Once the DOM is ready...
window.addEventListener('DOMContentLoaded', () => {
// ...query for the active tab...
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
// ...and send a request for the DOM info...
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', subject: 'DOMInfo'},
// ...also specifying a callback to be called
// from the receiving end (content script).
setDOMInfo);
});
});
popup.html。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<h3 style="font-weight:bold; text-align:center;">DOM Info</h3>
<table border="1" cellpadding="3" style="border-collapse:collapse;">
<tr>
<td nowrap>Total number of elements:</td>
<td align="right"><span id="total">N/A</span></td>
</tr>
<tr>
<td nowrap>Number of input elements:</td>
<td align="right"><span id="inputs">N/A</span></td>
</tr>
<tr>
<td nowrap>Number of button elements:</td>
<td align="right"><span id="buttons">N/A</span></td>
</tr>
</table>
</body>
</html>
関連
-
[解決済み] ChromeでCSSカスタムスタイルのボタンから青枠を削除する
-
[解決済み] Chromeの拡張機能です。Network.getResponseBody を実行しようとすると、「指定された識別子を持つリソースが見つかりません」と表示される。
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み] Firefox または Chrome ブラウザから HTTP POST リクエストを手動で送信する方法
-
[解決済み] Chromeを使用してASP.NET Web APIがXMLの代わりにJSONを返すようにするにはどうすればよいですか?
-
[解決済み] ChromeでコードからJavaScriptのブレークポイントを設定する方法は?
-
[解決済み] コンテンツスクリプトを使用して、ページコンテキスト変数と関数にアクセスする
-
[解決済み] jqueryでdivの要素がオーバーフローしていないかチェックする
-
[解決済み] JSHintの'+'前の改行不良の説明
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] JavaScriptで文字列を数値に変換する最速の方法は何ですか?
-
[解決済み] JavaScriptでjson-objectのキーを取得する [重複].
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] javascriptのキャンバスで画像をリサイズする (スムーズ)
-
[解決済み] jQueryのバージョン1、バージョン2、バージョン3の違いは何ですか?[クローズド]
-
[解決済み] JavaScriptデータフォーマット/プリティプリンタ