5

How do I force Tampermonkey to run/execute a script late after every document loaded by AJAX?

I wish to access those elements in my script and change them. But, even though I set @run-at to document-end in the setting page, it executes while the document wasn't loaded fully. And, it happens at this specific website !!

I tried these ways but was unsuccessful:

  1. Onload event.
  2. I tried while statement to check if all documents were loaded and then continue executing my script but it crashed and fell into infinite loop.
  3. I tried console to execute a function (but inaccessible by console).

So what do I do?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Hossein Alipour
  • 307
  • 1
  • 5
  • 13

2 Answers2

9

The content you want is being loaded by AJAX, so you need to use AJAX-compensation techniques in your script.

The easiest way to do that is to use waitForKeyElements(). Something like:

// ==UserScript==
// @name     _YOUR_SCRIPT_NAME
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/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 (
    "jQUERY SELECTOR TO THE NODE(S) YOU WANT",
    changeFontColor
);

function changeFontColor (jNode) {
    jNode.css ("color", "red");
}
Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Thank you, what if I want to do changeFontcolor when all children node has loaded/added to parent node , is it possible ? – Hossein Alipour Aug 03 '13 at 18:43
  • That's sort of what `waitForKeyElements` does. The concept of "all child nodes have loaded" often doesn't apply to AJAX pages, though. What specifically do you want different from this solution and why? – Brock Adams Aug 03 '13 at 22:29
  • I just need that waitForKeyElements call my function when all nodes have loaded once. but instead it call more then one time
    – Hossein Alipour Aug 04 '13 at 10:37
  • It doesn't normally work that way. Give a working example, so that we can see the issue. – Brock Adams Aug 04 '13 at 10:57
  • a lot of children here waitForKeyElements ( "#parent" , ...) I did something similar with SetInterval and ClearInterval successfully but now i Curious about that.
    – Hossein Alipour Aug 04 '13 at 11:54
0

If your script is holding up the page from loading, eg. on a Salesforce site, put your script's payload in a setTimeout() callback function. In this example, the background colour styles I am wanting to override are set by the original page's javascript which refuses to run until after TamperMonkey completes. The setTimeout in this script lets TamperMonkey run to completion and the page continue to load, but then runs the payload (my calls to GM_addStyle()) after a delay of one second.

:
// @grant  GM_addStyle
// @run-at document-idle
:
(function() {
    'use strict';
    setTimeout(function(){
           GM_addStyle(":root {--lwc-brandBackgroundPrimary:rgba(255, 176, 41, 1);}");
           GM_addStyle(":root {--lwc-brandBackgroundDark:rgba(237, 60, 24, 1);}");
           }, 1*1000);
})();