2013-03-17 15 views
22

Korzystając z PhantomJS, chciałbym wstrzyknąć trochę JS, jakby był dodatkowy znacznik <script> przed jakimikolwiek innymi znacznikami <script>. Dzieje się tak dlatego, że skrypty na stronie używają niektórych funkcji, których nie ma PhantomJS, a mianowicie Function.prototype.bind i window.webkitRequestAnimationFrame. Mam plik JS z niestandardowymi implementacjami tych dwóch i chciałbym, aby PhantomJS używał ich podczas uruchamiania skryptów na stronie.PhantomJS: wstrzykiwanie skryptu przed uruchomieniem innych skryptów.

Trudność polega na tym, że jeśli robię page.injectJs przed page.open, skrypt jest wstrzykiwany na pustą stronę i nie jest przenoszony do otwieranej strony.

Alternatywnie, jeśli zrobię page.injectJs after page.open, jest już za późno, ponieważ błędy JavaScript (niezdefiniowane funkcje) już wystąpiły.

Znalazłem sposób, który wydaje się działać, ale jest oczywiście hack:

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

Ten wstrzykuje to wiele razy (dwa razy dla każdego zasobu, najwyraźniej), ale to dobrze, bo mój skrypt jest idempotent . Chciałbym jednak wiedzieć, jak to zrobić: wstrzyknij go tylko raz i zanim uruchomione zostaną jakiekolwiek skrypty na stronie.

Dzięki :)

+0

dlaczego nie trzymać mieszania ze wszystkich plików, które chcesz wstrzyknąć gdzie kluczem jest plik, a wartość to czy został on wstrzykiwany lub nie i jeśli nie został wstrzyknięty następnie wstrzyknąć go? Czy możesz po prostu zatrzymać detektor zdarzeń po pierwszym uruchomieniu? – Nonconformist

Odpowiedz

23

nie sądzę istnieje „właściwy” sposób, aby wprowadzić taki scenariusz inny niż spinanie do zdarzeń. Spędziłem pół roku pracując masowo z PhantomJs i nie znalazłem żadnego sposobu na wstrzyknięcie zanim wszystkie błędy zaczną się dziać, ale po zakończeniu ładowania strony.

Chciałbym spróbować przejść przezInitialized, onLoadStarted, onLoadFinished. Wewnątrz haczyków zadzwoniłbym do page.evaluate(), który zmodyfikowałby DOM tak, by miał dodatkowe miejsce, które lubisz.

Myślę, że jeden z nich (haki) powinien dać ci odpowiedni czas, który chcesz.

Cheers

+9

Używanie 'onInitialized' i' injectJs' (przekazywanie względnej ścieżki do polyfills) działało idealnie w moim przypadku. –

+2

@MarcoLazzeri dzięki za komentarz, 'onInitialized' jest dokładnie tym, czego potrzebowałem w tym samym celu. – haynar

Powiązane problemy