2011-02-12 30 views
22

Estoy escribiendo un complemento para Firefox y usando el script greasemonkey para hacer eso (compilo el script del usuario usando esta herramienta http://arantius.com/misc/greasemonkey/script-compiler).cómo ejecutar el script greasemonkey antes de que se muestre el contenido de la página?

El problema es que la secuencia de comandos se ejecuta después de que la página está completamente cargada. Lo que significa que el usuario vería la página vista en su forma original y luego la secuencia de comandos aplicará los cambios que hice. Mi pregunta es si hay alguna manera de ejecutar el script del usuario antes de que el contenido de la página se muestre al usuario, por lo que el usuario solo vería la versión final del sitio web.

+0

Esto probablemente no sea posible con los complementos generados por ese compilador, que, como GM, se ejecuta después de que el DOM esté completamente cargado y funcione mediante inyección de JavaScript. Probablemente necesite usar más técnicas de extensión/complemento "típicas" para filtrar la página a medida que se descarga. Es decir, debe escribir una extensión, no portar un script de GM. –

+0

Incluso si escribe una extensión, el navegador comenzará a mostrar la página en su forma original antes de que esté completamente cargada. – Neil

Respuesta

24

EDITAR: Esta publicación se creó antes de la implementación de la clave @run-at en Greasemonkey. Como notó Blaise, de Greasemonkey 0.9.8 puede que la secuencia de comandos se ejecute tan pronto como la página comience a cargarse.

@run-at document-start se describe en el wiki de la siguiente manera:

Start es la nueva versión 0.9.8 de como. La secuencia de comandos se ejecutará antes de que se inicie la carga de cualquier documento , por lo tanto, antes de que se ejecuten las secuencias de comandos o se carguen las imágenes.

Tenga en cuenta que esto significa ejecutar el script (potencialmente) antes de la creación del DOM y puede dar lugar a un comportamiento inusual/inusual. Necesitará (un poco) más que solo este drop-in de una sola línea.

Hay algunos detalles más sobre el Greasemonkey Wiki: http://wiki.greasespot.net/Metadata_Block#.40run-at

Side-nota: La información que tengo a la mano está específicamente relacionado con Greasemonkey en el navegador. No estoy seguro de si @run-at document-start funciona bien con el compilador de secuencias de comandos: sugiero vivir peligrosamente ... Pruébalo y descúbrelo. ;]



Actualmente no es posible ejecutar una secuencia de comandos de usuario antes de cargar la página.

Para detener el parpadeo utilizando las versiones actuales de Greasemonkey, que podría intentar agregar un estilo de usuario a su perfil de Firefox (que luego se deshace con el script) como se describe en el Greasemonkey wiki pero esto también requeriría que cada uno de sus usuarios a hacer lo mismo para beneficiarse de esto.

Es algo que se ha deseado durante mucho tiempo y mirando a través de issue #1103 en el sitio Github de Greasemonkey, un prototipo de trabajo parece haber sido hecho (pero no hay ninguna escala de tiempo para que esto se añadió a una versión que yo sepa)

+2

Ese error se ha corregido y ahora puede ejecutar scripts antes de que la página cargue agregando esto a la sección de metadatos: '@ run-at document-start' – Blaise

+0

Cheers Blaise - He actualizado mi respuesta para reflejar los cambios en Greasemonkey desde el principio publicando la respuesta. No estoy seguro de qué tan bien '@ run-at document-start' funciona con el compilador de secuencias de comandos ya que no he estado involucrado con Greasemonkey desde hace bastante tiempo. – kwah

2

Utilizando el @run-at document-start como se sugiere en la respuesta de @kwah mi script ejecutado antes de que el contenido que quería manipular estuviera en el cuerpo del documento. Como solución alternativa, configuré un intervalo de ejecución de mi script 5 veces/segundo hasta document.readyState == "complete" (o hasta que hayan pasado 20 segundos).

Esto funcionó bien para mi caso:

// ==UserScript== 
// ... 
// @run-at  document-start 
// ==/UserScript== 

var greasemonkeyInterval = setInterval(greasemonkey, 200); 
var greasemonkeyStart = (new Date()).getTime(); 

function greasemonkey() { 

    // ... 

    // waiting for readyState (or timeout) 
    if (
     (new Date()).getTime() - greasemonkeyStart > 20000 
     || document.readyState == "complete" 
    ) { 
     clearInterval(greasemonkeyInterval); 
    } 

}; 

Si usted está más seguro de que el contenido estará allí en documentReady creo que algo como esto sería más preferible:

function greasemonkey() { 

    if (
     document.readyState != "interactive" 
     && document.readyState != "complete" 
    ) { 
     return; 
    } 

    // ... 

    clearInterval(greasemonkeyInterval); 

} 
2

Además de las respuestas anteriores, he encontrado una solución que funciona sin problemas, al igual que las versiones anteriores de Firefox & GreaseMonkey. En primer lugar, de gestión al debe establecerse en el momento más temprano, por lo que el documento de inicio:

// @run-at  document-start 

Debido a que el DOM probablemente no se carga, sin embargo, esperar a que el documento para obtener una readyState del interactivo:

document.onreadystatechange = function() { 
    if (document.readyState === "interactive") { 
     // Do something 
    } 
} 

Mientras que Greasemonkey implementa más o menos lo mismo con fin de documento, me he dado cuenta de que la técnica anterior funciona más rápido. El uso de esto ha resuelto todos los problemas que tenía en Firefox con pantallas intermitentes/saltantes en las páginas cuando los cambios DOM aparecían y cargaba la página como se pretendía con el usuario.

Cuestiones relacionadas