The userscript is designed to function exclusively on pages originating from the backend, rather than on the frontend in a single-page application

I have a userscript that I use with Greasemonkey/Tampermonkey.

It's set to run on facebook.com, where some pages are served from the backend during bootstrapping and others are loaded on the fly in the front-end using HRO, similar to how a Single Page Application (SPA) functions.

// ==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);

When I manually run this script in the console on SPA-like webpages, it works without any issues. However, when I try to execute it through Greasemonkey or Tampermonkey, it doesn't work on these specific types of webpages.

Is there a way to modify the script so that it functions correctly on SPA-style webpages as well?

Answer №1

When traditional methods like setTimeout, setInterval, and event delegation fail to work on their own, there is a workaround available. By pushing a state that includes these methods into memory, we can then replace the current state with it, effectively causing a change in the webpage's DOM content.

Here is a piece of code used to swap data loaded via AJAX instead of 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();

This information was gathered while reading here.

Answer №2

Another scenario where I had to tackle a similar issue involved utilizing the MutationObserver and inspecting the node.baseURI of each node within the mutation.addedNodes.

(async function() {
    'use strict';
    const targetSelector = '.quiz--answered';
    const observer = new MutationObserver(mutations => {
        if (!mutations.some(mutation => Array.from(mutation.addedNodes).some(node => node.baseURI.includes('/quiz/')))) {
            return;
        }
        const targetElement = document.querySelector(targetSelector);
        if (targetElement) {
            // implement logic with targetElement
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();

Answer №3

Encountering this issue multiple times led me to create a custom solution. I developed a simple library that enables me to execute scripts on URL changes, specify URLs using wildcards, and wait for specific elements if needed. This library is known as spa-runner.

import { run } from "@banjoanton/spa-runner";


const handler = () => {
    console.log("hello world!");
}

const config = {
    urls: ["http://*.facebook.com/*"],
    runAtStart: true,
};

const unsubscribe = run(handler, config);

Answer №4

After going through this specific documentation, it is clear that this code is designed to function effectively for single page applications when changing the location:

// ==UserScript==
...
// @match        https://subdomain.domain.tld/*
// @match        http://subdomain.domain.tld/*
// @grant        window.onurlchange
// ==/UserScript==

(function() {
    'use strict';
    if (window.onurlchange === null) {
        window.addEventListener('urlchange', (info) => {
            if (Object.values(info)[0].includes("/path/to/certainlocation")) {
                // your code here
            }

        });
    }
})();

It's important to note that this may not be effective if you directly visit the certain location, but adjustments can be made to address that issue. Alternatively, a separate userscript could be created that specifically targets that particular location, like so:

// @match       https://subdomain.domain.tld/path/to/certainlocation
// @match       http://subdomain.domain.tld/path/to/certainlocation

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AJAX is malfunctioning

I'm having trouble getting my JQuery to trigger the sanitize function. I want to retrieve the value from the input field labeled "name" and display it in the path input field. However, it doesn't seem to be working. The code is written on a page ...

How can I implement user account functionality with only JavaScript in an Angular frontend and Node.js/Express server?

Many resources I've come across utilize php or a similar language. With an Angular frontend and Node/express server code in place, but no backend yet, I'm uncertain about how to approach user sign-up. ...

Babel continues to encounter issues with async/await syntax, even with all the necessary presets and plugins installed

I am encountering a compiler error while attempting to compile an async/await function using Babel. Below is the function in question: async function login(username, password) { try { const response = await request .post("/api/login") . ...

Retrieve the query result using MYSQLI in an Ajax request and display it in an HTML document

When making an Ajax call in an HTML file to retrieve multiple rows of data from a database query, I am struggling to display the result back in the HTML file. index.html: <!DOCTYPE html> <html> <head> <script src="https://ajax.go ...

The Angular bootstrap popover vanishes as soon as the mouse hovers over it

Currently, I am facing an issue with an angular bootstrap popover on some text. The problem arises when the user tries to click on a link inside the popover as it disappears. Additionally, when changing from one popover to another, the previous one does no ...

Guide on linking JavaScript files in Node.js

I am having trouble getting my javascript to work properly. My javascript files are located in the public/javascripts directory. app.js app.use(express.static(path.join(__dirname, 'public'))); views/layout.pug doctype html html head ti ...

Exploring the process of dynamically inserting choices into an array of HTML dropdown menus using a combination of Php, AJAX, and jQuery

My task involves populating an HTML array of 10 select fields with jQuery every time a div-popup is called. The purpose of this form is to facilitate the batch approval of staffing requests for hundreds of employees by upper management, organized by depart ...

Is employing absolute paths in our confidential Node dependencies a good idea?

I have recently organized our codebase's React components into a separate dependency to make them reusable across different projects. To improve readability, all components now utilize Webpack aliases: import TestComponent from 'components/TestCo ...

Why does Vue continuously insert undefined values when adding non-consecutive indexes to an array?

In my application, users can select values from a dropdown list and add them to an array by clicking the "add" button. The goal is to use the selected value's id as the index in the array. For example: List of Values 1 - Apple 3 - Bananas 8 - P ...

Troubleshooting Angular Reactive Forms: Issue with Binding Dynamic Select Dropdown Value

I currently have two arrays of data: AssociatedPrincipals, which contains previously saved data, and ReferencePrincipals, which consists of static data to populate dropdown controls. I am facing difficulties in displaying/selecting the previous value from ...

What is the best way to ensure that an iframe adjusts its height to fit the content within a tabbed container?

Is there a way to dynamically set the height of an iframe to match the content inside it when clicking on a tabbed plane? Initially, I used a fixed height of 1000px. How can this be achieved? <div class="container-fluid text-center"> <div ...

The HTML table is not fully filled with data from the XML file

Trying to populate an HTML table using XML data retrieved from an AJAX call is proving to be a challenge for me. The main issue I am facing is the inability to fully populate the HTML table. Being new to AJAX, understanding how XML interpretation works an ...

Firefox triggers drag events while passing over a div scrollbar

I am looking to create a file drag and drop feature using a styled div: When dragging files over the div, I want the border color to change When dragging files out of the div, I want the border color to revert back to the original In Firefox 35 (Ubuntu) ...

Leverage the hidden glitch lurking within Vue

While working with SCSS in vue-cli3, I encountered a strange bug where using /deep/ would result in errors that I prefer not to deal with. Code Running Environment: vue-cli3 + vant + scss CSS: /deep/ .van-tabs__content.van-tabs__content--animated, .va ...

Finding the distance between two coordinates using Mapbox is easy once you understand how to utilize

Currently, I am in the process of learning how to utilize the Mapbox API within my node application. One of my objectives is to execute calculations on the backend, particularly obtaining the distance between two sets of coordinates. I'm struggling w ...

The jQuery keyup event initiates multiple times, increasing exponentially with each trigger

I recently added a search bar with auto-complete functionality to my website. The search bar queries the database for elements that begin with the text entered by the user as they type. Although it works well, I noticed that every time the user inputs ano ...

Using Vue's v-bind directive with a single set of curly braces expression

Currently, I am delving into the world of Vue.js to broaden my knowledge and gain practical experience. While following a tutorial, I encountered an interesting scenario involving the addition of a class to a span element based on a condition within a v-f ...

Issues with lazy loading in swiper.js when trying to display multiple images per slide

I recently tried using swiper.js and had success with the lazy loading demo. However, I encountered an issue where only one image per slide was showing up, despite wanting to display 4 images per slide. <div class="swiper-container"> <div cla ...

Steps for dynamically expanding a textarea in Selenium WebDriver when the element path is constantly changing

I am facing a challenge with resizing a textarea that has a dynamic xpath. I am unable to use the following JavascriptExecutor commands: (JavascriptExecutor) driver.executeScript("document.getElementById('someID').setAttribute('rows', ...

Is the jQuery AJAX call using POST method being retrieved as $_GET?

Below is a snippet of code that I've successfully implemented: <script type="text/javascript"> $(document).ready(function() { // Initializing the table $('#table_1').tableDnD({ onDrop: function(table, row) { $.tab ...