Chrome扩展程序如何将数据从内容脚本发送到popup.html

我知道这个问题已经在很多帖子中问过了,但老实说我不明白。我不熟悉JavaScript,Chrome扩展程序和其他所有功能,并且已经完成了此类课程。因此,我需要制作一个插件,该插件将使用跨域请求在任何给定页面上计算DOM对象。到目前为止,我已经可以使用Chrome

Extension

API来实现这一目标。现在的问题是,我需要在contentScript.js文件的popup.html页面上显示数据。我不知道该怎么做,我已经尝试阅读文档,但是在chrome中发消息我只是不知道该怎么做。

以下是到目前为止的代码。

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>

eventPage.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"});

});

});

});

contentScript

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方法等)。

我没有亲自测试您的代码,但是从快速的概览中,我相信更正以下内容可能会导致一个可行的解决方案(尽管不是非常接近最佳):

  1. 在 :更改内容脚本的顺序,将jquery放在首位。根据 :

“ js” […]将注入匹配页面的JavaScript文件列表。这些 在此数组中 注入。

(强调我的)

  1. 在 :移动 块 的onMessage听者回调。


也就是说,这是我建议的方法:

控制流:

  1. 内容脚本将被注入到每个符合某些条件的页面中。
  2. 注入后,内容脚本会将消息发送到事件页面(又称非持久性背景页面),事件页面会将页面操作附加到选项卡。
  3. 加载页面操作弹出窗口后,它将立即向内容脚本发送一条消息,询问其所需的信息。
  4. 内容脚本处理请求,并做出响应,以便页面操作弹出窗口可以显示信息。


目录结构:

          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扩展程序如何将数据从内容脚本发送到popup.html 的全部内容, 来源链接: utcz.com/qa/411815.html

回到顶部