www3 www w3schools code certification browsers asp javascript jquery html google-chrome google-chrome-extension

www - w3schools javascript certification



Chrome Extension cómo enviar datos desde el script de contenido a popup.html (2)

Sé que esto se ha pedido en numerosas publicaciones, pero sinceramente no las recibo. Soy nuevo en JavaScript, extensiones de Chrome y todo, y tengo esta asignación de clase. Por lo tanto, necesito hacer un complemento que cuente los objetos DOM en cualquier página dada usando Solicitudes de dominios cruzados. Hasta ahora, he podido lograr esto con la API de extensión de Chrome. Ahora el problema es que necesito mostrar los datos en mi página popup.html desde el archivo contentScript.js. No sé cómo hacer eso. Intenté leer la documentación pero enviar mensajes en Chrome. Simplemente no puedo entender qué hacer.

siguiente es el código hasta el momento.

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 });

Cualquier ayuda sería apreciada y por favor evita cualquier noobness que hice :)


Aunque definitivamente estás en la dirección correcta (y bastante cerca del final), hay varias (malas) prácticas en tu código (por ejemplo, inyectar una biblioteca completa (jquery) para una tarea tan trivial, declarar permisos innecesarios, hacer superflores llamadas a métodos API, etc.).
No probé el código yo mismo, pero a partir de una descripción general rápida, creo que corregir lo siguiente podría dar como resultado una solución de trabajo (aunque no muy cercana a la óptima):

  1. En manifest.json : cambie el orden de los scripts de contenido, poniendo jquery primero. De acuerdo con los documentos pertinentes :

    "js" [...] La lista de archivos JavaScript que se inyectará en páginas coincidentes. Estos se inyectan en el orden en que aparecen en este conjunto.

    (énfasis mío)

  2. En contentscript.js : Mueva el bloque chrome.runtime.sendMessage ({...}) dentro de la devolución de llamada del oyente onMessage .

Dicho esto, este es mi enfoque propuesto:

Flujo de control:

  1. Se inyecta una secuencia de comandos de contenido en cada página que coincida con algunos criterios.
  2. Una vez inyectados, los scripts de contenido envían un mensaje a la página del evento (página de fondo no persistente) y la página del evento adjunta una página = acción a la pestaña.
  3. Tan pronto como se carga la ventana emergente de acción de página, envía un mensaje al script de contenido, solicitando la información que necesita.
  4. El script de contenido procesa la solicitud y responde para que la ventana emergente de acción de página pueda mostrar la información.

Estructura de directorios:

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": ["*://*..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(function (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(function (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 function 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'', function () { // ...query for the active tab... chrome.tabs.query({ active: true, currentWindow: true }, function (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>


Puede usar localStorage para eso. Puede almacenar cualquier información en formato de tabla hash en la memoria del navegador y luego acceder a ella en cualquier momento. No estoy seguro de si podemos acceder a localStorage desde el script de contenido (se bloqueó antes), intente hacerlo usted mismo. A continuación, le indicamos cómo hacerlo a través de su página de fondo (paso primero los datos de la secuencia de comandos de contenido a la página de fondo y luego los guardo en localStorage):

en contentScript.js:

chrome.runtime.sendMessage({ total_elements: totalElements // or whatever you want to send });

en eventPage.js (su página de fondo):

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse){ localStorage["total_elements"] = request.total_elements; } );

Luego puede acceder a esa variable en popup.js con localStorage ["total_elements"].

Tal vez pueda acceder a localStorage directamente desde la secuencia de comandos de contenido en los navegadores modernos. Entonces no necesita pasar los datos a través de su página de fondo.

Buena lectura sobre localStorage: http://diveintohtml5.info/storage.html