admin管理员组文章数量:1336659
I have the following userscript I run on Greasemonkey/Tampermonkey.
I run it on facebook
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/*
// @include https://*.facebook/*
// @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?
I have the following userscript I run on Greasemonkey/Tampermonkey.
I run it on facebook.
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./*
// @include https://*.facebook./*
// @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?
Share Improve this question asked Aug 1, 2017 at 0:09 sangokosangoko 3511 silver badge13 bronze badges4 Answers
Reset to default 6In 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.
From reading this documentation, this code would work for SPA 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
}
});
}
})();
Note this would not work if you visit the certain location directly, but that could easily be fixed, or you could create another userscript that only matches that certain location, eg:
// @match https://subdomain.domain.tld/path/to/certainlocation
// @match http://subdomain.domain.tld/path/to/certainlocation
For a similar use case, I used MutationObserver and checked node.baseURI
of each node in each mutation.addedNodes
.
(async function() {
'use strict';
const selector = '.quiz--answered';
const observer = new MutationObserver(mutations => {
if (!mutations.some(mutation => Array.from(mutation.addedNodes).some(node => node.baseURI.includes('/quiz/')))) {
return;
}
const elm = document.querySelector(selector);
if (elm) {
// work with elm
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();
I have stumbled upon this problem several times myself, I ended up writing a simple lib to deal with this. It allows me to run the script on URL changes, define the URLs with wildcards and wait for specific element if I want to. It's called spa-runner.
import { run } from "@banjoanton/spa-runner";
const handler = () => {
console.log("hello world!");
}
const config = {
urls: ["http://*.facebook./*"],
runAtStart: true,
};
const unsubscribe = run(handler, config);
本文标签:
版权声明:本文标题:javascript - Userscript works only on pages served from backend, but not on frontend in a SPA way - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742419961a2471459.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论