Pergunta

Eu tenho um script Greasemonkey que funciona muito bem no Firefox e na Opera. Eu luto para fazê -lo funcionar no Chrome, no entanto. O problema está injetando uma função na página que pode ser invocada pelo código da página. Aqui está o que estou fazendo até agora:

Primeiro, recebo uma referência ajudante ao Instantado Para Firefox. Isso me permite ter o mesmo código para FF e Opera (e Chrome, pensei).

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

Em seguida, injeto uma função na página. É realmente apenas um invólucro muito fino que não faz nada além de invocar a função correspondente no contexto do meu script GM:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

Então, há a função correspondente diretamente no meu script:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

Por fim, injetei algum html na página com um link para invocar a função.

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);

Para resumir: no Firefox, quando o usuário clicar nesse link injetado, ele executará a chamada de função na INSOVA, que aciona um tempo limite que chama a função correspondente no contexto do meu script GM, que faz o processamento real. (CORRECE -me se eu estiver errado aqui.)

No Chrome, eu apenas recebo um erro "ReferenceError não capturado: o setConfigoption não está definido". E, de fato, entrar "Window.SetConfigoption" no console produz um "indefinido". No Firebug e no console do desenvolvedor de ópera, a função está lá.

Talvez haja outra maneira de fazer isso, mas algumas das minhas funções são invocadas por um objeto flash na página, o que acredito que é necessário que eu tenha funções no contexto da página.

Eu dei uma olhada rápida no Alternativas para a ida e meia No Wiki Greasemonkey, mas todos parecem muito feios. Estou completamente na faixa errada aqui ou devo procurar mais de perto isso?

RESOLUÇÃO: eu segui Max S. ' adendo E funciona no Firefox e no Chrome agora. Como as funções que eu precisava estar disponíveis para a página precisavam ligar para as regulares, movi todo o meu script para a página, ou seja, ela está completamente envolvida na função que ele chamou de 'main ()'.

Para tornar a feia extra desse hackear um pouco mais suportável, eu poderia pelo menos abandonar o uso de não -seguro e WrappedJSobject agora.

Eu ainda não consegui conseguir o Runner de escopo de conteúdo Do Wiki Greasemonkey trabalhando. Deve fazer o mesmo e parece executar muito bem, mas minhas funções nunca são acessíveis a <a> Elementos da página, por exemplo. Ainda não descobri por que isso é.

Foi útil?

Solução

A única maneira de se comunicar com o código em execução na página no Chrome é através do DOM, então você terá que usar um hack como inserir um <script> Marque com seu código. Observe que isso pode provar o buggy se o seu script precisar ser executado antes de tudo na página.

EDITAR: Aqui está como a boa extensão de alerta isso faz isso:

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

Outras dicas

Eu tenho isto :

contentscript.js:

function injectJs(link) {
var scr = document.createElement('script');
scr.type="text/javascript";
scr.src=link;
document.getElementsByTagName('head')[0].appendChild(scr)
//document.body.appendChild(scr);
}

injectJs(chrome.extension.getURL('injected.js'));

injetado.js:

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

main();

Eu dei uma olhada rápida no Alternativas para a ida e meia No Wiki Greasemonkey, mas todos parecem muito feios. Estou completamente na faixa errada aqui ou devo procurar mais de perto isso?

Você deve procurar, porque está disponível apenas a opção. Eu prefiro usar Hack de localização.

myscript.user.js:

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

location.href="javascript:(function(){" + myFunc + "})()"

exemplo.com/mypage.html

<script>
myFunc() // Hello World!
</script>

Claro, é feio. Mas está funcionando bem.


O método Runner de Escopo de Conteúdo, mencionado por Max S. é melhor que o Hack de localização, porque é mais fácil de depurar.

As outras respostas forçam você a usar expressões de função, importar um arquivo adicional externo ou use um Hack de remendado há muito tempo.

Esta resposta adicionará o JavaScript à página diretamente do seu código -fonte. Ele usará o ECMAScript 6 (ES6) Literais de modelos Para colocar a string javascript de várias linhas sem esforço na página.

var script = document.createElement('script'); 
script.type = "text/javascript"; 
script.innerHTML = ` 
   function test() {
      alert(1);
   }
`;
document.getElementsByTagName('head')[0].appendChild(script);

Observe os backsticks `` que definem o início e o final de uma sequência de várias linhas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top