14

我有一个正在尝试为其创建 Greasemonkey 脚本的应用程序。它利用大量的 jQuery 和 AJAX 来动态加载内容。

我注意到每次加载新项目时URL 都会发生变化,即使页面没有刷新。

每次 URL 更改时,我可以在页面上放置一个侦听器以重新启动脚本吗?

4

2 回答 2

19

您如何执行此操作取决于站点/应用程序以及您尝试执行的操作。 这是您的选择,首先是最简单和最强大的:

  1. 不要试图捕捉 URL 变化。 使用调用来waitForKeyElements()对您首先要操作的各个页面的部分进行操作。 这巧妙地处理了所有其他方法固有的大量时序问题。
    另请参阅:“在 AJAX 驱动的站点上选择和激活正确的控件”

  2. 只需轮询 URL 更改。 它很简单并且在实践中效果很好,除了技术#1之外,时间问题比其他所有问题都少。

  3. 如果站点使用 AJAX 更改片段(又名“哈希”),则触发hashchange事件。唉,越来越少的 AJAX 站点这样做了。

  4. 使用Mutation Observers<title>监控标签的变化。大多数AJAX 页面也足以更改标题。不过,这可能会在您的目标内容加载之前触发。

  5. 侵入history.pushState函数。这可以更快地通知页面更改,但 95% 的时间,它会在您的目标元素加载之前触发。您通常仍需要一个计时器。另外,它在用户脚本环境中带来了跨范围的问题。


作为参考,这里是一个轮询示例。它仍然是最好的、简单的、跨浏览器的、包罗万象的方法:

/*--- Note, gmMain () will fire under all these conditions:
    1) The page initially loads or does an HTML reload (F5, etc.).
    2) The scheme, host, or port change.  These all cause the browser to
       load a fresh page.
    3) AJAX changes the URL (even if it does not trigger a new HTML load).
*/
var fireOnHashChangesToo    = true;
var pageURLCheckTimer       = setInterval (
    function () {
        if (   this.lastPathStr  !== location.pathname
            || this.lastQueryStr !== location.search
            || (fireOnHashChangesToo && this.lastHashStr !== location.hash)
        ) {
            this.lastPathStr  = location.pathname;
            this.lastQueryStr = location.search;
            this.lastHashStr  = location.hash;
            gmMain ();
        }
    }
    , 111
);

function gmMain () {
    console.log ('A "New" page has loaded.');
    // DO WHATEVER YOU WANT HERE.
}
于 2013-09-25T06:21:52.790 回答
-1

"I've noticed the URL does change each time" with a lot of AJAX would lead me that they are using the History API. If that's the case, take a look at window.onpopstate. That should fire on each URL change using the History API.

于 2013-09-24T18:36:20.530 回答