2

我正在尝试构建一个脚本来更改Stack Overflow 的用户配置文件部分中标签页面上标签的颜色/布局。

我测试了脚本并且它运行了。问题是,当我单击排序选项 [ votes ] 和 [ name ]时,我想重新运行它。

我试过了:

  1. 触发 jQueryready事件。
  2. 附加一个onclick处理程序(这是无用的,因为它在页面重新加载之前运行)。
  3. 将事件侦听器附加load到带有标签等的表上,但无济于事。

我确信我在这里遗漏了一些非常明显的东西。我怀疑涉及到一些异步重新加载,但我不明白完成这项工作所需的操作是什么。

任何人都可以解释我缺少什么(或指向一些解释它的文档)吗?

4

1 回答 1

4

这是一个常见的问题。该页面使用 AJAX 仅替换其部分内容。因此触发 jQuery 的ready事件将不起作用,因为它只会在初始的完整页面加载后触发。

以下是常用的解决方法/方法供参考。我只推荐第一个:

  1. 使用强大的轮询实用程序,例如waitForKeyElements()。这需要加载一个外部脚本(通常不是问题),并且它需要 jQuery,无论如何您都应该使用它。下面详细介绍这种方法。

  2. 触发hashchange事件。当 AJAX 更改页面时,有些页面可以很好地触发此事件。不幸的是,Stack Overflow 不是那些“礼貌”的网站之一。;-)

  3. 触发对 URL 的其他更改。当 AJAX 更改内容时,有些页面可以很好地更改 URL。Stack Overflow确实做到了这一点。
    不幸的是,在 SO 的情况下,URL 立即更改,而实际页面更改发生在可变(不可预测的)延迟之后。这意味着您还必须使用其他技术之一。

  4. 拦截页面的 AJAX。这可能会变得复杂和混乱,并且通常仍然需要轮询或延迟,因为实际的页面更改可能会在 AJAX 请求完成后的可变时间间隔内发生。在页面可能产生的多种类型中识别正确的 AJAX 请求也可能很烦人。

  5. 使用MutationObservers。这可能是最强大的技术,并且是变革驱动而不是轮询。但在大多数情况下,它是矫枉过正的,实施起来可能很棘手,并且可能会因 CPU 峰值而“冻结”计算机。

  6. 请注意,一种较旧的技术Mutation Events已过时并被弃用,这是有充分理由的。请勿尝试使用它,尽管某些浏览器尚未删除此功能。


在几乎所有针对 AJAX 驱动页面的脚本中,我们真正想要的只是对某些类型的内容采取行动。艺术是识别该内容,然后很容易使用像waitForKeyElements()这样的实用程序在添加或替换我们的目标有效负载时触发。

在您的情况下,内容似乎是出现在此 HTML 中的标签列表:

<div id="user-tab-tags">
    ...
    <div class="user-tab-content">
        <table class="user-tags">
            ...
        </table>
    </div>
    ...
</div>

table.user-tags每次更改该选项卡的排序/分页选项时都会被替换。

因此,该内容的 jQuery 选择器将是:

"#user-tab-tags div.user-tab-content table.user-tags"

更改样式的完整脚本是:

// ==UserScript==
// @name     _AJAX_compensation techniques
// @include  http://stackoverflow.com/users/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

waitForKeyElements (
    "#user-tab-tags div.user-tab-content table.user-tags",
    customStyleUserTags
);

function customStyleUserTags (jNode) {
    jNode.css ("background", "lime");
    //***** YOUR CODE HERE *****
}
于 2012-12-21T07:40:57.623 回答