Run a Greasemonkey script on changes to an internal tab (not a browser tab)?

我的未来我决定 提交于 2019-12-23 02:44:12

问题


I'm trying to build a script that alters the coloring/layout of tags on the tag page in the user-profile section of Stack Overflow.

I tested the script and it runs. The problem is that I would like to re-run it when I click on the sort options [votes] and [name].

I have tried:

  1. Triggering off the jQuery ready event.
  2. Attaching an onclick handler (which is useless since it runs before the page reloads).
  3. Attaching a load event listener to the table with the tags, etc., to no avail.

I am sure I am missing something very obvious here. I suspect that there is some async reload involved, but I can't understand what the required action to make this work is.

Can anyone explain what I am missing (or point me to some documentation that explains it)?


回答1:


This is a common problem. That page is using AJAX to replace just part of its content. Therefore triggering off of jQuery's ready event won't work, as that only fires after the initial, full page load.

Here are the usual workarounds/approaches for reference. I only recommend the first one:

  1. Use a robust polling utility like waitForKeyElements(). This requires loading an external script (not normally a problem), and it requires jQuery, which you should be using anyway. This approach is detailed below.

  2. Trigger off the hashchange event. Some pages are nice enough to fire this event when AJAX changes the page. Unfortunately, Stack Overflow is not one of those "polite" sites. ;-)

  3. Trigger off other changes to the URL. Some pages are nice enough to change the URL when AJAX changes the content. Stack Overflow does do this.
    Unfortunately, the URL changes immediately in SO's case, while the actual page changes occur after a variable (unpredictable) delay. Meaning you must also use one of the other techniques.

  4. Intercept the page's AJAX. This can get complicated and messy, and often times a poll or delay is still needed, as the actual page changes may occur a variable interval after the AJAX request has finished. Identifying the correct AJAX request, out of the many types the page may make, can also be tiresome.

  5. Use MutationObservers. This can be the most powerful technique, and is change driven versus polling. But it's overkill in most situations, can be tricky to implement, and can "freeze" computers with CPU spikes.

  6. Note that an older technique, Mutation Events, is obsolete and deprecated for good reasons. Do not attempt to use it, although some browsers haven't removed this functionality yet.


In almost all scripting against AJAX-driven pages, all we really want is to act on certain kinds of content. The art is to identify that content, then it's easy to use a utility like waitForKeyElements() to fire whenever our targeted payload is added or replaced.

In your case, the content appears to be the tag listing which appears in this HTML:

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

With table.user-tags being replaced every time you change that tab's sort/pagination options.

So the jQuery selector for that content would be:

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

and a complete script to change the styling would be:

// ==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 *****
}


来源:https://stackoverflow.com/questions/13976495/run-a-greasemonkey-script-on-changes-to-an-internal-tab-not-a-browser-tab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!