Gli script di contenuto Chrome non funzionano: l'ascoltatore DOMContentLoaded non viene eseguito

Sto provando a codificare l'estensione che corregge errori di errori su un forum.

Sto cercando di accedere al tag <p> , con script di contenuto, ma non cambia nulla (usando il codice qui sotto):

 document.addEventListener("DOMContentLoaded", function() { document.getElementsByTagName("P")[4].innerHTML = "correct_word"; }); 

Non cambia niente quando viene aggiunto come estensione, apparentemente se ho la pagina, e metto lo script lì, tutti i lavori. qualche idea?

Il mio file manifest.json :

 { "manifest_version": 2, "name": "Extension", "description": "Description", "version": "1.0", "content_scripts": [{ "run_at": "document_end", "matches": ["http://example.com/"], "js": ["script.js"] }], "web_accessible_resources": ["Filedeleted(really).html"] } 

Conosco script di contenuto e le pagine WWW hanno sandbox differenti, forse lo script di contenuto non può accedere alla pagina (e al tag)?

DOMContentLoaded script dopo l'evento che stai ascoltando per gli incendi (in questo caso, DOMContentLoaded ). Quindi, nessun codice che si dispone nell'ascoltatore non verrà eseguito, perché l'evento non si accende mai dopo aver aggiunto l'ascoltatore.

Nelle estensioni Chrome e Firefox WebExtensions, quando si specifica un tempo per iniettare uno script di contenuto , è ansible specificare "document_start" , "document_end" o "document_idle" . 1 In un manifest.json questo è il valore indicato per la properties; run_at . Per tabs.executeScript() , è la properties; runAt .

  • document_start
    L'iniezione avviene prima della creazione del DOM, o degli script provenienti dalla pagina in esecuzione. Ciò significa che document.body e document.head non esistono ancora. Gli events di load DOMContentLoaded e di window non hanno ancora sparato. È ansible aggiungere le cose al DOM aggiungendole al document.documentElement . Potrebbe essere necessario utilizzare un MutationObserver per guardare gli elementi interessati a essere aggiunti al DOM o attendere un evento come DOMContentLoaded per indicare che il DOM è disponibile.
  • document_end (predefinito)
    L'iniezione avviene dopo che il DOM è completo, ma prima che siano caricate le subresources (ad esempio immagini e fotogrammi). Questo è di solito dopo che DOMContentLoaded ha sparato, ma prima che si verifica l'evento di load della window .
  • document_idle
    L'iniezione avviene a volte dopo il document_end e subito dopo l'incendio della window load . La risposta a "Quando viene eseguito un run_at: document_idle script di contenuto?" indica che questa è la prima di:

    • Dopo che si verifica l'evento di load della window , oppure
    • 200ms dopo l'evento DOMContentLoaded sparato.

    Ciò significa che il tuo script di contenuto sarà iniettato dopo che DOMContentLoaded ha sparato, ma l'evento di load della window può o non ha già sparato.

Quando si ascolta DOMContentLoaded o il load window , è necessario controllare prima il file document.readyState

Ogni volta che si utilizza un ascoltatore DOMContentLoaded o un listener di load window , è necessario controllare sempre il document.readyState prima di aggiungere l'ascoltatore per assicurarsi di aggiungere l'ascoltatore prima dell'evento DOMContentLoaded (o prima dell'evento di load essere licenziati, se è quello che stai ascoltando). Questo dovrebbe essere l'abitudine normale quando si desidera ascoltare questi events. Se si aggiunge l'ascoltatore dopo l'avvio dell'evento, l'ascoltatore non verrà mai eseguito.

Per aggiungere un listener DOMContentLoaded , è necessario utilizzare qualcosa come:

 if(document.readyState === 'loading') { document.addEventListener('DOMContentLoaded',afterDOMLoaded); } else { afterDOMLoaded(); } function afterDOMLoaded(){ //Everything that needs to happen after the DOM has initially loaded. } 

Per aggiungere un listener di load window , puoi utilizzare qualcosa come:

 if(document.readyState !== 'complete') { window.addEventListener('load',afterWindowLoaded); } else { afterWindowLoaded(); } function afterWindowLoaded(){ //Everything that needs to happen after the window is fully loaded. } 

  1. Se si utilizza tabs.executeScript() , il valore specificato per runAt indica solo la prima volta che si desidera iniettare lo script. Se si esegue tabs.executeScript() prima di tale periodo, l'iniezione viene ritardata fino all'ora specificata. Si noti che per il document_start il punto in cui l'esecuzione di tabs.executeScript() sarà valida per una nuova pagina è un argomento complesso, che merita una propria domanda / risposta.
  2. Porzioni di questa risposta sono state copiate dalla mia risposta a "Rileva e gestisci un clic del button nella pagina HTML triggers" .