14

有什么方法可以检测到document.title/head > title通过 Javascript 的更改?我想通过 Google Chrome 扩展内容脚本检测到这一点,所以我无法在目标页面的 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是使此工作正常所需的全部内容。

最后在调用中包装三个换标题方法setTimeout只是为了演示目的;没有这个,标题值变化太快,以至于 WebKitMutationObserver 不会单独报告每个变化,因为 MutationObserver 旨在在执行观察者回调之前在短时间内累积变化。

如果不需要检测通过最后一个仅限 jQuery 的方法所做的标题更改,则childList: true可以从该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 回答