2013-08-23 2 views
8

Angenommen, ich habe eine Erweiterung, die geladen wird, wenn Sie auf einer YouTube-Videoseite ankommen.Ich habe festgestellt, dass die Erweiterung höchstwahrscheinlich gewonnen hat, wenn man mit den Chrome-Tasten hin und her navigiert nicht laden.Die Chrome-Erweiterung wird bei der Browsernavigation auf YouTube nicht geladen

Als Beispiel habe ich 2 Dateien, das Manifest:

{ 
    "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"] 
     } 
    ] 
} 

und die contentscript

alert("loaded"); 

Der Alarm immer nicht angezeigt wird, wenn hin und her navigieren. Wie kann ich das überwinden, damit die Erweiterung jedes Mal geladen wird?

+0

Ähnliche http://stackoverflow.com/a/34100952/72321 – Dennis

Antwort

17

YouTube hat eine Testversion mit pushState-basierter Navigation gestartet. Im Allgemeinen können solche Navigationen nur in Inhaltsskripten erkannt werden, indem Code eingefügt wird, der Aufrufe an history.replaceState/history.pushState abfängt (oder indem Sie das Ereignis chrome.webNavigation.onHistoryStateUpdated auf der Hintergrundseite verwenden).

Der Rest dieser Antwort ist spezifisch für YouTube.
YouTube zeigt eine (rot) Statusleiste oben auf der Seite unter Last. Dieser Fortschrittsbalken wird mit einem CSS-Übergang animiert. Da Übergangsereignisse platzen, können Sie einen Übergangsereignis-Listener an <body> binden und die Navigation in diesen Fällen überprüfen.

Sie haben Ihre Content-Skript auf *://www.youtube.com/* statt *://www.youtube.com/watch*, einzuführen, da pushstate verwendet werden können, von / zu /watch.. zu navigieren.

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(); 

Hinweis: Diese Methode hängt davon ab, dass der Fortschrittsbalken eingefügt wird. Immer wenn Google beschließt, die ID der Fortschrittsanzeige umzubenennen oder die Fortschrittsleiste vollständig zu entfernen, funktioniert Ihr Code nicht mehr.

Anmerkung 2: Dies funktioniert nur für aktiv Tabs. Wenn Sie Navigation Änderungen erkennen müssen, während die Lasche nicht fokussiert ist, dann müssen Sie ein window.onfocus und window.onblur Ereignis binden, und prüfen, ob document.title zwischen diesen Ereignissen verändert hat.

+0

Vielen Dank für diese Antwort. Mit dieser Methode funktioniert es, aber es ist nicht so früh wie DOMContentLoaded, es scheint, das ist gleichbedeutend mit "load", gibt es trotzdem den "DOMContentLoaded" -ähnlichen Punkt zu erkennen? – Noitidart

+1

@Noitidart Wenn Sie so schnell wie möglich benachrichtigt werden möchten, können Sie an das Ereignis 'transitionstart' binden, um nach Änderungen im Dokument zu suchen (mit 'setTimeout' oder' setInterval'). Wenn Sie das gewünschte Element gefunden haben, heben Sie die Registrierung des Übergangsstart-Ereignisses auf, und beenden Sie die Abfrage, und rufen Sie Ihren benutzerdefinierten Rückruf auf. Um sicherzustellen, dass keine CPU-Zyklen verschwendet werden, kombinieren Sie dies mit dem Ereignis transitionend; Wenn Ihre Abfragelogik zu diesem Zeitpunkt noch nichts erkannt hat, entfernen Sie die Ereignis-Listener, stoppen Sie den Poller und rufen Sie den Callback auf. –

+0

Genius Idee @RobW Danke! Ich habe versucht, 'window.onpopstate = function (e) {console.log (e)}' hinzuzufügen, ich dachte, das würde den Trick machen, aber ich bekomme keine Rückrufe dazu. – Noitidart

Verwandte Themen