Force Tampermonkey to run/execute script late
Asked Answered
K

3

7

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?

Kathlyn answered 1/8, 2013 at 13:33 Comment(0)
M
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");
}
Magyar answered 2/8, 2013 at 2:14 Comment(5)
Thank you, what if I want to do changeFontcolor when all children node has loaded/added to parent node , is it possible ?Kathlyn
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?Magyar
I just need that waitForKeyElements call my function when all nodes have loaded once. but instead it call more then one time <div id="parent"></div>Kathlyn
It doesn't normally work that way. Give a working example, so that we can see the issue.Magyar
<div id="parent"> <div class="child"></div> a lot of children here </div> waitForKeyElements ( "#parent" , ...) I did something similar with SetInterval and ClearInterval successfully but now i Curious about that.Kathlyn
D
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);
})();
Dehaven answered 27/5, 2022 at 9:41 Comment(0)
O
0

Another solution consists in checking if the key element is present, and try again later if it is not:

function myFunction() {
    var targetElement = document.querySelector("desired-element-property")

    if (targetElement == null) {
        // The element is not loaded yet, try again later
        setTimeout(myFunction, 500)
    } else {
        // The element is there, we can execute our code
        …
    }
};

window.addEventListener('load', function() {
    setTimeout(myFunction, 500)
}, false);
Oxyacid answered 5/6 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.