2012-07-27 14 views
13

Czy istnieje sposób na wykrycie zmiany na document.title/head > title przez Javascript? Chcę to wykryć za pomocą skryptu rozszerzenia treści Google Chrome, więc nie mogę podłączyć kodu do strony JS strony docelowej, w której dokonywana jest rzeczywista zmiana tytułu.Wykryj zmianę tytułu dokumentu za pomocą kodu JavaScript

Znalazłem WebKitMutationObserver który teoretycznie powinien być w stanie wykryć zmiany w head > title, ale to nie działa we wszystkich przypadkach:

// set up an observer for the title element 
var target = document.querySelector('title'); 
var observer = new WebKitMutationObserver(function(mutations) { 
    mutations.forEach(function(mutation) { 
     console.log(mutation); 
    }); 
}); 
var config = { attributes: true, childList: true, characterData: true }; 
observer.observe(target, config); 

// this jQuery statement fires the observer as expected ... 
$('head > title').text('foo'); 

// ... but this doesn't: 
document.querySelector('title').innerText = 'cheezburger'; 

// ... and neither does this: 
document.title = 'lorem ipsum'; 

pomysłów?

+0

Wspominałeś o JavaScript, ale widzę, że używasz JQuery. Czy jesteś otwarty na jQuery lub prosty JavaScript? – anAgent

+0

Widziałem tylko obserwatorów mutacji strzelających do zmian w ciele. – Utkanos

Odpowiedz

28

Znalazłem w pełni działające rozwiązanie, które jest tylko małą modyfikacją przykładu zamieszczonego w oryginalnym poście.

// set up an observer for the title element 
var target = document.querySelector('head > title'); 
var observer = new window.WebKitMutationObserver(function(mutations) { 
    mutations.forEach(function(mutation) { 
     console.log('new title:', mutation.target.textContent); 
    }); 
}); 
observer.observe(target, { subtree: true, characterData: true, childList: true }); 

// all three of these methods correctly fire the mutation observer 
setTimeout(function() { document.title = 'foo'; }, 1000); // the usual method 
setTimeout(function() { document.querySelector('head > title').innerText = 'bar'; }, 2000); // DOM method 
setTimeout(function() { $('head > title').text('cheezburger'); }, 3000); // jQuery-only method 

Dodanie subtree: true było wszystkim, co było potrzebne, aby to działało prawidłowo.

Zawijanie trzech metod zmiany tytułu w rozmowach setTimeout na końcu służy tylko do celów demonstracyjnych; bez tego wartość tytułu zmienia się tak szybko, że WebKitMutationObserver nie zgłasza każdej zmiany osobno, ponieważ MutationObserver jest przeznaczony do gromadzenia zmian przez krótki czas przed wykonaniem wywołania zwrotnego obserwatora.

Jeśli nie trzeba wykrywać zmian tytułu wykonanych za pomocą ostatniej metody tylko jQuery, właściwość childList: true można pominąć w linii observer.observe; tylko characterData: true jest potrzebny do wykrycia dwóch pierwszych metod zmiany tytułu.

+1

Wystarczy krótka uwaga, że ​​wystąpił problem: http://code.google.com/p/chromium/issues/detail?id=134322 – psema4

+0

+1 tylko dla '$ (" head> title "). ("cheezburger"); ': ') –

2

Masz zarówno JQuery i JavaScript w swoim przykładzie kodu. Nie jestem pewien, czy ogranicza się tylko do JavaScriptu, ale oto jak można to zrobić z jQuery

Jeśli chcesz wywołać zmianę, przyjrzeć: http://api.jquery.com/trigger/

jQuery

$(document).ready(function() { 
    $("title", "head").change(function() { 
     console.log("Title has changed"); 
    }); 
    //Trigger Change 
    $("title","head").text("New Title").trigger("change"); 
}); 
+0

Niestety działa to tylko wtedy, gdy zmiana jest uruchamiana ręcznie, jak na przykład; jeśli użyto 'document.title = 'foobar';', detektor zdarzeń nie uruchamia się. – joelpt

+0

Nie jesteś pewien, co masz zamiar, ale spójrz na: http://stackoverflow.com/a/413455/1220302 i sprawdź, czy nie spowoduje żadnych przyszłych problemów. Tylko uwaga na ten temat, może możesz zaktualizować swoje pytanie za pomocą detialów; dlaczego zmieniasz tytuł dokumentu? – anAgent

+0

Nie zmieniam tytułu dokumentu, ale chcę, aby moje rozszerzenie Chrome było w stanie wykryć, kiedy dana strona aktualizuje swój tytuł. – joelpt

Powiązane problemy