2013-03-17 23 views
22

Utilizzando PhantomJS, vorrei inserire del JS come se ci fosse un tag <script> extra prima di qualsiasi altro tag <script>. Questo perché gli script nella pagina utilizzano alcune funzioni che PhantomJS non possiede, ovvero Function.prototype.bind e window.webkitRequestAnimationFrame. Ho un file JS con implementazioni personalizzate dei due e vorrei che PhantomJS li usasse quando si eseguono gli script sulla pagina.PhantomJS: iniettare uno script prima di eseguire qualsiasi altro script

La difficoltà è che se faccio page.injectJs prima di page.open, lo script viene iniettato in una pagina vuota e non viene trasferito alla pagina che viene aperta.

In alternativa, se faccio page.injectJs dopo page.open, è troppo tardi perché gli errori JavaScript (funzioni indefinite) si sono già verificati.

ho trovato un modo che sembra funzionare, ma è ovviamente un hack:

page.onResourceReceived = function() { 
    page.injectJs('phantom-hacks.js') 
}; 

Questo inietta molte volte (due volte per ogni risorsa, a quanto pare), ma va bene perché il mio script è idempotente . Tuttavia, mi piacerebbe sapere il modo corretto per farlo: iniettarlo solo una volta e prima che vengano eseguiti gli script sulla pagina.

Grazie :)

+0

perché non tenere un hash di tutti i file che si desidera iniettare in cui la chiave è il file e il valore è se è stato iniettato o no e se non è stato iniettato poi iniettare? Oppure potresti semplicemente interrompere il listener di eventi dopo la prima esecuzione? – Nonconformist

risposta

23

Non credo ci sia un modo "corretto" per iniettare tale script diverso aggancio agli eventi. Ho passato mezzo anno a lavorare in modo massiccio con PhantomJs e non ho trovato modo di iniettare prima che inizino tutti gli errori, ma dopo che la pagina ha finito di caricarsi.

Vorrei provare a passare su Initialized, onLoadStarted, onLoadFinished. All'interno dei ganci chiamerei page.evaluate(), che modificerebbe semplicemente DOM per avere questo extra qualunque posto desideri.

Penso che uno di loro (i ganci) dovrebbe darti il ​​giusto tempismo che desideri.

Acclamazioni

+9

L'uso di 'onInitialized' e' injectJs' (passando il percorso relativo ai polyfill) ha funzionato perfettamente nel mio caso. –

+2

@MarcoLazzeri grazie per il tuo commento, 'onInitialized' è esattamente ciò di cui avevo bisogno per lo stesso scopo. – haynar

Problemi correlati