Los scripts de contenido se ejecutan en un entorno de "mundo aislado" . Tienes que inyectar tu state()
método en la página misma.
Cuando desee utilizar una de las chrome.*
API en el script, debe implementar un controlador de eventos especial, como se describe en esta respuesta: Extensión de Chrome: recuperación del mensaje original de Gmail .
De lo contrario, si no tiene que usar chrome.*
API, le recomiendo que inyecte todo su código JS en la página agregando una <script>
etiqueta:
Tabla de contenido
- Método 1: inyectar otro archivo
- Método 2: inyectar código incrustado
- Método 2b: uso de una función
- Método 3: usar un evento en línea
- Valores dinámicos en el código inyectado
Método 1: inyectar otro archivo
Este es el método más fácil / mejor cuando tienes mucho código. Incluya su código JS real en un archivo dentro de su extensión, digamos script.js
. Luego, deje que su script de contenido sea el siguiente (explicado aquí: Google Chome "Acceso directo a la aplicación" Javascript personalizado ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Nota: Si usa este método, el script.js
archivo inyectado debe agregarse a la "web_accessible_resources"
sección ( ejemplo ). Si no lo hace, Chrome se negará a cargar su script y mostrará el siguiente error en la consola:
Negar la carga de chrome-extension: // [EXTENSIONID] /script.js. Los recursos deben estar listados en la clave de manifiesto web_accessible_resources para que las páginas que se encuentren fuera de la extensión puedan cargarlos.
Método 2: inyectar código incrustado
Este método es útil cuando desea ejecutar rápidamente un pequeño fragmento de código. (Consulte también: ¿Cómo deshabilitar las teclas de acceso rápido de Facebook con la extensión de Chrome? ).
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Nota: los literales de plantilla solo son compatibles con Chrome 41 y versiones posteriores. Si desea que la extensión funcione en Chrome 40-, use:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
Método 2b: uso de una función
Para una gran porción de código, no es factible citar la cadena. En lugar de usar una matriz, se puede usar una función y stringificar:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Este método funciona, porque el +
operador en cadenas y una función convierte todos los objetos en una cadena. Si tiene la intención de usar el código más de una vez, es aconsejable crear una función para evitar la repetición del código. Una implementación podría verse así:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Nota: ¡Dado que la función está serializada, el alcance original y todas las propiedades enlazadas se pierden!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Método 3: usar un evento en línea
A veces, desea ejecutar un código inmediatamente, por ejemplo, ejecutar un código antes de <head>
crear el elemento. Esto se puede hacer insertando una <script>
etiqueta con textContent
(ver método 2 / 2b).
Una alternativa, pero no recomendada, es usar eventos en línea. No se recomienda porque si la página define una política de seguridad de contenido que prohíbe los scripts en línea, entonces los escuchas de eventos en línea están bloqueados. Los scripts en línea inyectados por la extensión, por otro lado, aún se ejecutan. Si aún desea utilizar eventos en línea, así es como:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Nota: Este método supone que no hay otros escuchas de eventos globales que manejen el reset
evento. Si lo hay, también puede elegir uno de los otros eventos globales. Simplemente abra la consola de JavaScript (F12), escriba document.documentElement.on
y seleccione los eventos disponibles.
Valores dinámicos en el código inyectado
Ocasionalmente, debe pasar una variable arbitraria a la función inyectada. Por ejemplo:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
Para inyectar este código, debe pasar las variables como argumentos a la función anónima. ¡Asegúrese de implementarlo correctamente! Lo siguiente no funcionará:
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
La solución es usar JSON.stringify
antes de pasar el argumento. Ejemplo:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Si tiene muchas variables, vale la pena usar JSON.stringify
una vez, para mejorar la legibilidad, de la siguiente manera:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);