通过 ajax 更改页面时如何运行 Greasemonkey 脚本?

Posted

技术标签:

【中文标题】通过 ajax 更改页面时如何运行 Greasemonkey 脚本?【英文标题】:How can I run a Greasemonkey script when page changed via ajax? 【发布时间】:2012-06-17 16:32:52 【问题描述】:

我有那个脚本:

// ==UserScript==
// @name     example
// @include  http://xxx*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// ==/UserScript==

var findElem = function(elems, text) 
    for (var i = 0; i < elems.length; i++) 
        if (elems[i].textContent == text) 
            return elems[i];
         else 
            var result = findElem(elems[i].children, text);
            if (result != undefined) 
                return result;
            
        
    
    return;


switch (document.getElementById('my_id').value) 
    case "1":
        findElem(document.documentElement.children, "blabla1").click();
        break;
    case "2":
        findElem(document.documentElement.children, "blabla2").click();
        break;
    case "3":
        findElem(document.documentElement.children, "blabla3").click();
        break;
    case "4":
        findElem(document.documentElement.children, "blabla4").click();
        break;
    default:
        break;

它工作正常,但它只适用于主页加载。我想在通过 ajax 更改页面时运行它。我该怎么做?

请举例说明你的答案。我是新手。我不知道如何在你的答案中使用东西。

【问题讨论】:

准确列出正在发生的变化。显示足够多的 html 结构,我们可以选择准确的选择器——链接到它的目标页面并不是非常困难。 【参考方案1】:

由于浏览器的环境是事件驱动的,您必须设置一个计时器,绑定到您要查找的更新周围发生的一些事件。或者,您可以包装更新并在挂钩后调用您的代码的函数。显然,您需要将您的用户脚本代码包装在某个函数中以便重用。

这是一个使用setInterval 设置计时器的示例(脚本顶部仍然相同):

setInterval(function()
    switch (document.getElementById('my_id').value) 
        case "1":
            findElem(document.documentElement.children, "blabla1").click();
            break;
        case "2":
            findElem(document.documentElement.children, "blabla2").click();
            break;
        case "3":
            findElem(document.documentElement.children, "blabla3").click();
            break;
        case "4":
            findElem(document.documentElement.children, "blabla4").click();
            break;
        default:
            break;
    
, 1000) // if AJAX updates happen with some specific interval, set same number here to minimize useless work

【讨论】:

定时器监听其实是个不错的解决方案,如果页面内容的ajax重载也是由setTimeout/setInterval触发的话。 谢谢,但我不知道我能不能这样做。你能举个例子或编辑我的代码吗? 那么,您真的应该阅读有关事件和计时器的基本文档。从示例中可以看出,更改是微不足道的。【参考方案2】:

如果您的主机使用 jQuery,那么您可以使用 ajaxSuccess 或 ajaxComplete:

function mainCode()
    // your script logic here ...
    switch (document.getElementById('my_id').value) 
        // truncated to save space
    


$(document).ready(function()
    mainCode();
    unsafeWindow.$(document).ajaxSuccess(function(e, xhr, opt) 
        mainCode();
    );
);

【讨论】:

【参考方案3】:

您可以在每次更改 html 时使用mutation event handler 来触发您的函数。但是,浏览器支持不是最好的;)

【讨论】:

谢谢,但我不知道如何使用它。你能举个例子或编辑我的代码吗? 你有没有看到关于mutation events are deprecated 的部分,Mozilla 不推荐它们,甚至 Firefox 现在也支持它们(但将来不会)。 @BrockAdams 我知道,但这是一种可能的方式,反正有Mutation Observers 在路上。

以上是关于通过 ajax 更改页面时如何运行 Greasemonkey 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

键盘输入时,如何在Ajax调用URL更改后停止MVC页面刷新

在 Oro 平台上使用 Ajax 加载模板时如何触发页面组件事件?

使用 ajax 在不刷新站点的情况下更改 mongoDB 中的某些项目

是否可以通过 Ajax 更改页面源内容变量

AJAX 日历更新页面 rails 4

使用 Ajax 实时更改数据库