14

Javascriptへのdocument.title/経由での変更を検出する方法はありますか?head > titleこれをGoogleChrome拡張コンテンツスクリプトで検出したいので、実際のタイトル変更が行われるターゲットページのJSにコードを実際に接続することはできません。

理論的にはへの変更を検出できるはずのWebKitMutationObserverを見つけましたがhead > title、すべての場合に機能するとは限りません。

// 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';

何か案は?

4

2 に答える 2

36

元の投稿に投稿した例を少し変更しただけの、完全に機能するソリューションを見つけました。

// 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

subtree: trueこれを正しく機能させるために必要だったのは、 の追加だけでした。

最後の呼び出しでの 3 つのタイトル変更メソッドのラップは、setTimeoutデモンストレーションのみを目的としています。これがないと、MutationObserver はオブザーバー コールバックを実行する前に短期間で変更を蓄積するように設計されているため、タイトルの値が急速に変更されるため、WebKitMutationObserver は各変更を個別に報告しません。

最後の jQuery 専用メソッドを介して行われたタイトルの変更を検出する必要がない場合は、プロパティを行childList: trueから省略できます。最初の 2 つのタイトル変更方法を検出するためobserver.observeだけに必要です。characterData: true

于 2012-07-27T19:12:14.603 に答える
2

コード例には JQuery と Javascript の両方があります。JavaScript だけに制限されているかどうかはわかりませんが、jQuery でそれを行う方法は次のとおりです。

変更をトリガーする場合は、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");
});
于 2012-07-27T18:35:17.967 に答える