12

因此,对我的问题进行基本描述。

我现在(终于)有一个正在工作的扩展程序,它将电话号码包装在一种标签中。

它现在正在工作,但是我遇到了基于用户操作或基于 ajax 请求通过 JS 动态加载的任何内容的问题

例如,如果我单击 hotmail 电子邮件并打开它,脚本会起作用,但仅当我刷新页面以便电子邮件加载并调用我的 contentscript 时。

我想过通过让用户单击扩展的图标来解决这个问题,但这并不是真正要求的功能。

如果 Chrome 中有一种方法可以收听 ajax 请求(似乎有)http://code.google.com/chrome/extensions/webRequest.html 这就是我想要做的,但我不确定如何来实现这一点。我把它当作听众吗?

我想出了另一种基于 DOM 何时更改的方法,但这使得加载需要很长时间,DOM 中发生的事情太多了,无法做到这一点。我需要监听 AJAX 请求并在它们完成后再次运行我的代码。

任何帮助甚至是正确方向的指针都会很棒=)

如果这是一个愚蠢的问题,请很好,我保证我一直在谷歌搜索并搜索答案,但我似乎找不到任何东西。有可能我知道的不够多,甚至无法提出正确的问题。我已经使用 javascript 大约两个星期了......所以我的学习曲线一直在艰难攀升。

4

2 回答 2

12

当你说...

我想出了另一种基于 DOM 何时更改的方法,但这使得加载需要很长时间,DOM 中发生的事情太多了,无法做到这一点。我需要监听 AJAX 请求并在它们完成后再次运行我的代码。

...您在哪里使用 Mutation Events 或 Mutation Observers?因为我认为观察者在哪里解决这个问题。我以前从未对 Observers 做过任何事情并使用过Mutation Summary。它似乎可以做你想做的事,除非它直到文件准备好/空闲(不确定是哪个)才开始观察,所以你可能必须对准备好的文件进行扫描,然后解雇观察者。
这是我的测试代码的样子(在内容脚本中)......

handleChanges = function(summaries) {
    // There may be more things to ignore
    var ignore = {
        SCRIPT: true,
        NOSCRIPT: true, 
        CDATA: true,
        '#comment': true
    }
    summaries.forEach(function(summary) {
        summary.added.forEach(function(node) {
            if (!ignore[node.nodeName] || (node.parentNode && !ignore[node.parentNode.nodeName]) && node.nodeValue.trim()) {
                node.nodeValue='PAEz woz ere - '+node.nodeValue;
            }
        })
    })

}

var observer = new MutationSummary({
    callback: handleChanges,
    // required
    rootNode: document,
    // optional, defaults to window.document
    observeOwnChanges: false,
    // optional, defaults to false
    queries: [{
        characterData: true
    }]
});

另一种检查 XMLHttpRequest 的方法是劫持它,它看起来像(在文档开始时的内容脚本中)......

function injectScript(source) {

    var elem = document.createElement("script"); //Create a new script element
    elem.type = "text/javascript"; //It's javascript
    elem.innerHTML = source; //Assign the source
    document.documentElement.appendChild(elem); //Inject it into the DOM
}

injectScript("("+(function() {

    function bindResponse(request, response) {
        request.__defineGetter__("responseText", function() {
            console.warn('Something tried to get the responseText');
            console.debug(response);
            return response;
        })
    }

    function processResponse(request,caller,method,path) {
        bindResponse(request, request.responseText);
    }

    var proxied = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function(method, path, async) {
            var caller = arguments.callee.caller;
            this.addEventListener('readystatechange', function() {
                if (this.readyState === 4)
                    processResponse(this,caller,method,path);
            }, true);
        return proxied.apply(this, [].slice.call(arguments));
    };
}).toString()+")()");

...我不是在超级棒的Supper Happy Fun 博客上学到的。
但正如您现在可能知道的那样,对于 ajax 驱动的站点来说,这还不够。通常,您必须为该站点编写一些特定的内容,或者 Mutation Observer 可能会满足您的需求。

于 2012-08-04T19:50:38.490 回答
0

这是使用的更新答案MutationObserver,因为MutationSummary不再起作用:

var observer = new MutationObserver(function(mutationsList) {
  console.log(`Something has changed`);
});

observer.observe(document.querySelector('.whatever'), {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true
});
  • 确保将.whatever选择器更改为您感兴趣的任何类/ID。
  • 如果您对选择器的子修改感兴趣,请确保true/false在选项中指定。subtree
于 2020-09-19T17:27:50.433 回答