【问题标题】:How do I reload a Greasemonkey script when AJAX changes the URL without reloading the page?当 AJAX 更改 URL 而不重新加载页面时,如何重新加载 Greasemonkey 脚本?
【发布时间】:2013-09-24 18:32:21
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript ajax greasemonkey


    【解决方案1】:

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

    1. 不要试图捕捉 URL 更改。 Use calls to waitForKeyElements() to act on the parts of the various pages that you wanted to manipulate in the first place. 这巧妙地处理了所有其他方法固有的一系列时序问题。
      另请参阅:"Choosing and activating the right controls on an AJAX-driven site"

    2. Just poll for URL changes.它很简单,在实践中效果很好,除了技术#1之外,时间问题比其他所有方法都少。

    3. 如果站点使用 AJAX 来更改 片段(也称为“哈希”),fire on the hashchange event。唉,越来越少的 AJAX 网站这样做了。

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

    5. Hack into the history.pushState function. 这可以更快地通知页面更改,但在 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.
    }
    

    【讨论】:

    • 事实证明,有时这会在页面更改之前启动,因此解决方案是将您在 gmMain() 中所做的任何事情放在 setTimeout() 中(我使用 500 毫秒),除此之外,当您导航回来时,再次调用该函数,您可以找到 AJAX 内容的容器,并在第一个元素中添加一个类,如果该类存在,则不执行任何操作。
    【解决方案2】:

    “我注意到 URL 每次都会改变”与很多 AJAX 会导致我认为他们正在使用 History API。如果是这种情况,请查看window.onpopstate。这应该会在使用 History API 的每个 URL 更改时触发。

    【讨论】:

    猜你喜欢
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    相关资源
    最近更新 更多