我有一个正在尝试为其创建 Greasemonkey 脚本的应用程序。它利用大量的 jQuery 和 AJAX 来动态加载内容。
我注意到每次加载新项目时URL 都会发生变化,即使页面没有刷新。
每次 URL 更改时,我可以在页面上放置一个侦听器以重新启动脚本吗?
我有一个正在尝试为其创建 Greasemonkey 脚本的应用程序。它利用大量的 jQuery 和 AJAX 来动态加载内容。
我注意到每次加载新项目时URL 都会发生变化,即使页面没有刷新。
每次 URL 更改时,我可以在页面上放置一个侦听器以重新启动脚本吗?
您如何执行此操作取决于站点/应用程序以及您尝试执行的操作。 这是您的选择,首先是最简单和最强大的:
不要试图捕捉 URL 变化。 使用调用来waitForKeyElements()
对您首先要操作的各个页面的部分进行操作。 这巧妙地处理了所有其他方法固有的大量时序问题。
另请参阅:“在 AJAX 驱动的站点上选择和激活正确的控件”。
只需轮询 URL 更改。 它很简单并且在实践中效果很好,除了技术#1之外,时间问题比其他所有问题都少。
如果站点使用 AJAX 更改片段(又名“哈希”),则触发hashchange
事件。唉,越来越少的 AJAX 站点这样做了。
使用Mutation Observers来<title>
监控标签的变化。大多数AJAX 页面也足以更改标题。不过,这可能会在您的目标内容加载之前触发。
侵入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.
}
"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.