Search code examples
javascriptajaxconsolesingle-page-applicationuserscripts

Userscript works only on pages served from backend, but not on frontend in a SPA way


I have the following userscript I run on Greasemonkey/Tampermonkey.

I run it on facebook.com which serves some of the webpages from backend, in bootstrapping, and some others on the fly, in front-end, via HRO, just as a Single Page Application (SPA) would.

// ==UserScript==
// @name        facebook
// @namespace   nms
// @include     http://*.facebook.com/*
// @include     https://*.facebook.com/*
// @version     1
// @grant       none
// ==/UserScript==

setTimeout( () => {
    // generalStuff:
        document.querySelectorAll(' #left_nav_section_nodes, .fbChatSidebar ').forEach( (e)=> {
            e.style.visibility = "hidden";
        });

}, 1000);

If I run this script on console, even in HRO based webpages, it runs fine, but when runned from Greasemoneky/Tampermonkey it won't run in these particular webpages.

How could I make the script to work without problem on SPA-like webpages as well?


Solution

  • In such a case when setTimeout, setInterval, and event delegation doesn't work by themselves, it is possible to push a state that implements them into the memory, then replacing the existing state with it, so that the webpage's DOM content will change.

    Here's a code used to replace data that was loaded with AJAX instead directly from PHP:

    let utilityFunc = ()=> {
        var run = (url)=> {
           // insert your code here
        };
    
        var pS = window.history.pushState;
        var rS = window.history.replaceState;
    
        window.history.pushState = function(a, b, url) {
            run(url);
            pS.apply(this, arguments);
        };
    
        window.history.replaceState = function(a, b, url) {
            run(url);
            rS.apply(this, arguments);
        };
    
    utilityFunc();
    

    That's what I understood from reading here.