2013-08-23 8 views
8

Supponiamo di avere un'estensione che viene caricata quando arrivi a una pagina video di YouTube. Ho notato che quando si naviga avanti e indietro usando i pulsanti Chrome, l'estensione ha vinto molto probabilmente caricare.L'estensione Chrome non si sta caricando nella navigazione del browser su YouTube

Per fare un esempio, ho 2 file, il manifesto:

{ 
    "name": "back forth", 
    "version": "0.1", 
    "manifest_version": 2, 
    "description": "back forth", 
    "permissions": ["storage", "*://www.youtube.com/watch*"], 
    "content_scripts": [ 
     { 
      "matches": ["*://www.youtube.com/watch*"], 
      "js": ["contentscript.js"] 
     } 
    ] 
} 

e il contentscript

alert("loaded"); 

L'avviso non mostra sempre durante la navigazione avanti e indietro. Come posso superare questo problema, in modo che l'estensione venga caricata ogni volta?

+0

simile http://stackoverflow.com/a/34100952/72321 – Dennis

risposta

17

YouTube ha avviato una prova con navigazione basata su pushState. In generale, tali navigazioni possono essere rilevate solo negli script di contenuto mediante l'iniezione di codice che intercetta le chiamate a history.replaceState/history.pushState (o utilizzando l'evento chrome.webNavigation.onHistoryStateUpdated nella pagina di sfondo).

Il resto di questa risposta è specifico per YouTube.
YouTube mostra una barra di avanzamento (rossa) nella parte superiore della pagina durante il caricamento. Questa barra di avanzamento è animata utilizzando una transizione CSS. Poiché gli eventi di transizione sono in bolla, puoi associare un listener di eventi di transizione a <body> e controllare la navigazione in questi casi.

è necessario inserire lo script contenuto in *://www.youtube.com/* invece di *://www.youtube.com/watch*, perché pushState può essere utilizzato per navigare da / a /watch...

function afterNavigate() { 
    if ('/watch' === location.pathname) { 
     alert('Watch page!'); 
    } 
} 
(document.body || document.documentElement).addEventListener('transitionend', 
    function(/*TransitionEvent*/ event) { 
    if (event.propertyName === 'width' && event.target.id === 'progress') { 
     afterNavigate(); 
    } 
}, true); 
// After page load 
afterNavigate(); 

Nota: questo metodo dipende dal fatto che la barra di avanzamento è inserita. Ogni volta che Google decide di rinominare l'ID della barra di avanzamento o di rimuovere completamente la barra di avanzamento, il codice smetterà di funzionare.

Nota 2: funziona solo per le schede attive. Se è necessario rilevare le modifiche di navigazione mentre la scheda non è a fuoco, è necessario associare un evento window.onfocus e window.onblur e verificare se è stato modificato document.title tra questi eventi.

+0

Grazie per questa risposta. Usando questo metodo funziona, ma non è così sinonimo di DOMContentLoaded, sembra che questo sia equivalente a 'load', è comunque in grado di rilevare il punto' DOMContentLoaded'? – Noitidart

+1

@Noitidart Se vuoi davvero ricevere una notifica il prima possibile, puoi associare l'evento 'transitionstart', eseguire il polling delle modifiche del documento (usando' setTimeout' o 'setInterval'). Quando hai trovato l'elemento desiderato, annulla la registrazione dell'evento transitionstart + interrompi il polling + richiama la richiamata personalizzata. Per assicurarti di non sprecare i cicli della CPU, combina questo con l'evento transitionend; se la logica di polling non ha rilevato nulla in quel punto, rimuovere i listener di eventi, interrompere il polling e richiamare il callback. –

+0

Idea geniale @RobW grazie! Ho provato ad aggiungere 'window.onpopstate = function (e) {console.log (e)} 'pensavo che avrebbe fatto il trucco ma non ho ricevuto alcun callback ad esso. – Noitidart

Problemi correlati