No se pueden llamar funciones a scripts de contenido haciendo clic en la imagen

Esto es lo que tengo aquí:

"manifiesto.json"

{..."permissions": [
"https:/mywebsite.com/"],"content_scripts": [{
  "matches" : ["http://*/*", "https://*/*"],
  "js": ["js/jquery-1.7.2.min.js", "contentScript1.js", "contentScript2.js"],
  "all_frames" : true,
  "run_at": "document_end"
} ]}

"contentScript1.js"

$(document).ready(function() {
$('#someDiv').load('https://mywebsite.com/index.html');}

"contentScript2.js"

function showMessage()
{alert ('Hello World!');}

"index.html"

<a href="" onclick="showMessage();"> <img src="https://mywebsite.com/images/myimage.png"></a>

Lo que realmente estoy haciendo aquí es inyectar una imagen en la que se puede hacer clic en el código de la página que estoy visitando y espero que al hacer clic en la imagen aparezca un mensaje de "Hola mundo". A pesar de que los scripts de contenido y la imagen se cargan con éxito, cuando hago clic en la imagen, la función no se llama y aparece el siguiente error en la consola:

Error de referencia no capturado: showMessage no está definido

Supongo que no encuentra la función ya que la busca en la web que le he inyectado el código y no en los scripts de contenido. Pero, ¿por qué es eso? Quiero decir, si llamo a la función dentro del script de contenido cuando se carga y no al hacer clic en la imagen, aparece el mensaje. ¿Alguien puede sacarme de aquí?

preguntado el 02 de julio de 12 a las 23:07

2 Respuestas

No entendiste mi solución para evitar conflictos no funciona con tu código actual. En lugar de usar $.noConflict, está envolviendo su función de inyección de secuencias de comandos en un $().ready método.

Tienes que eliminar jQuery de la "js" parte del manifiesto:

  "js": ["contentScript1.js"],

Y contentScript1.js

function injectJs(srcFile) {
    var scr = document.createElement('script');
    scr.src = srcFile;
    document.getElementsByTagName('head')[0].appendChild(scr);
}
injectJs(chrome.extension.getURL('js/jquery-min.js'));
injectJs(chrome.extension.getURL('js/yourscript.js'));

!Siempre ponerle js/yourscript.js a web_accessible_resources, para que se pueda utilizar:

"web_accessible_resources": [
    "index3.html",
    "js/jquery-min.js"
    "js/yourscript.js"
]

In js/yourscript.js, envuelva la lógica de su función en una función anónima junto con $.noConflict. $.noConflict(true) se utiliza para evitar conflictos con los scripts de la página. Restaura el valor original de $ y jQuery.

(function(jQuery, $) {
    // Here, you can do anything you want.
    // jQuery and $ refer to the same jQuery object from `js/jquery-min.js`

})(jQuery, jQuery.noConflict(true));

Después de volver a mirar su pregunta, noté que está cargando contenido a través de ajax: $('#someDiv').load(...). Cuando se inyecta el script, se ejecuta en el ámbito de la página. Es por eso que su llamada AJAX falla: la solicitud está bloqueada debido a la Política de mismo origen.

Ahora, podemos usar un enfoque diferente para arreglar su código. En lugar de mover la lógica del script de contenido a la página (mediante un script inyectado), modificamos la página index.html. El evento de clic no está preestablecido, sino que se agrega en el script de contenido. Por ejemplo:

"índice.html":

<a href="" id="showMessage"> <img src="https://mywebsite.com/images/myimage.png"></a>

"script de contenido2.js":

$('#showMessage').click(showMessage);

Respondido 04 Jul 12, 14:07

Rob, nunca dije que la solicitud de AJAX falla: el html se cargó correctamente. Sin embargo, es un enfoque muy interesante lo que describe aquí. Entonces, básicamente, voy a necesitar cambiar cada evento onclick, onmouseover que tengo en el html a las funciones .click y .hover jquery e incluirlas en un script de contenido. Entonces, de esta manera, ¡no es necesario inyectar ningún script! Jquery y mis scripts se cargarán como scripts de contenido. Sin embargo, parece que no funciona y que el html que inyecté no puede comunicarse con contentscript. ¿Lo has probado y funciona? - svatsi

@svatsi Los scripts de contenido solo se ejecutan cuando se carga la página. No se activa cuando se agrega contenido dinámicamente a través de AJAX. Si esa es la causa, puede solucionarlo usando $(document).on('click', 'selector', function(){ ... }) en lugar de $('selector').click(...); - Rob W

Ese es mi guión de contenido principal: pastie.org/4199199. Ese es el segundo script de contenido que estoy cargando también y quiero ocultar algunas imágenes e inicializar las cosas de 'rotonda': pastie.org/4199019 (sin embargo, las imágenes no permanecen ocultas y las cosas indirectas no se inicializan). Ahora, si cambio el segundo script de contenido a: pastie.org/4199094 y llame a 'runThis ()' al hacer clic en un evento como este: pastie.org/4199225 ENTONCES, el código en el segundo script de contenido se ejecuta con éxito y las imágenes se ocultan y se inicializan las cosas indirectas: svatsi

En el primer conjunto de guiones, está evaluando el runThis lógica cuando se carga la página. En el último conjunto de guiones, estás llamando runThis() al hacer clic. Esa es una gran diferencia... - Rob W

Sí, pero ¿por qué no funciona cuando se carga la página? También traté de poner todo en un solo script pero no funcionó. - svatsi

Creo que voy a responder a mi propia pregunta:

La razón por la que esto sucede es porque los scripts de contenido se ejecutan en un mundo aislado ver: http://code.google.com/chrome/extensions/content_scripts.html#execution-environment

Entonces, simplemente no puede llamar a las funciones, una vez que inyectó algún código html, en content_scripts para realizar algún trabajo en la página actual del usuario.

Lo que tienes que hacer es inyectar tus scripts en la página como lo haces con el código html. Asi que:

(1) agregue los archivos que desea inyectar en recursos web en su archivo de manifiesto, consulte: http://code.google.com/chrome/extensions/manifest.html#web_accessible_resources

"web_accessible_resources": [
"Script2.js",
 "index.html",
"jquery-1.7.2.min.js"]

(2) en contentScript1.js (cargar esto como un content_script)

 //inject your javascript files to the head of the page
function injectJs(srcFile) {
   var scr = document.createElement('script');
   scr.type="text/javascript";
   scr.src=srcFile;
   document.getElementsByTagName('head')[0].appendChild(scr);
}

injectJs(chrome.extension.getURL('jquery-1.7.2.min.js'));
injectJs(chrome.extension.getURL('Script2.js'));

//inject your html by loading query and passing your html page
$(document).ready(function() {
$('#someDiv').load(chrome.extension.getURL('./index.html'));}

¡Eso es todo!

Respondido 08 Feb 15, 04:02

Recomiendo encarecidamente contra inyectando jQuery directamente. Romperás muchas páginas que ya definen $. Asegúrate de usar $.noConflict, como sigue: (function($){ /*your code here*/ })(jQuery.noConflict(true)); (en Script2.js). - Rob W

Tienes toda la razón, lamentablemente hay conflictos. El problema parece ser la propia biblioteca jQuery y no el código que estoy ejecutando en Script2.js. Si no estoy inyectando JQuery lib, la página está bien; de lo contrario, puedo ver, por ejemplo, al seleccionar la opción en los menús desplegables de la página: algunos elementos no aparecen y puedo imaginar que también debe haber algunos conflictos en otro lugar. He leído la documentación que proporcionó, pero no entiendo cómo se puede resolver esto, ya que dije que el conflicto parece deberse a que estoy inyectando lib. me puedes dar mas detalles por favor?? - svatsi

Intente reducir el número de scripts a uno. Modificar Script2.js's código como lo hice en mi comentario anterior, péguelo después jQuery-min.jsy compruebe si el problema persiste. - Rob W

Hola Roberto y gracias por responder. He probado lo que me dijiste y el problema persiste. Inyecté solo jQuery-min.js a través de contentScript1.js que describí anteriormente. Incluso si no inyecto Script2.js, el problema persiste. También traté de inyectar versiones anteriores de jquery y sigo teniendo el mismo problema. ¿Lo has probado y te funciona bien? - svatsi

¿Puede publicar un ejemplo mínimo (manifiesto + scripts) para que pueda reproducir su problema? - Rob W

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.