这是我的用户脚本,用于更改访问链接的颜色。假设它能够与任何网站一起使用。
// ==UserScript==
// @name Change the color of visited links
// @description -
// @match *://*/*
// ==/UserScript==
function style(css) {
let head, style;
head = document.getElementsByTagName('head')[0];
if (!head) return;
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css.replace(/;/g, '!important;');
head.appendChild(style);
}
function links(anylink, link, visited, hover, active) {
style(`
${anylink} { outline: solid 1px; }
${link} { color: blue; }
${visited} { color: fuchsia; }
${hover} { color: red; }
${active} { color: yellow; }
`);
}
links('a:any-link , a:any-link *',
'a:link , a:link *',
'a:visited , a:visited *',
'a:hover , a:hover *',
'a:active , a:active *'
);
问题在于,在某些网站上,某些链接属于影子 DOM 元素,因此它们不受脚本的影响。如何解决这个问题?
您可以使用
document.querySelector(selector).shadowRoot
访问影子 DOM
从那里您需要使用
head
找到第一个 querySelectorAll
或默认为元素本身,然后在那里注入 CSS。
// setup example
const host = document.querySelector("#host");
const shadow = host.attachShadow({
mode: "open"
});
const span = document.createElement("span");
span.innerHTML = "I'm in the shadow DOM <a href='#'>link</a>";
shadow.appendChild(span);
function addToHeadOrSelf(elem, css) {
var head
if (elem.getElementsByTagName) {
head = elem.getElementsByTagName('head')[0];
}
if (elem.querySelectorAll) {
head = elem.querySelectorAll('head')[0]
}
if (!head) {
head = elem
}
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css.replace(/;/g, '!important;');
head.appendChild(style);
}
function style(css) {
addToHeadOrSelf(document, css)
var elementsWithShadowRoot = findElementsWithShadowRoot()
elementsWithShadowRoot.forEach(function(elem) {
addToHeadOrSelf(elem.shadowRoot, css)
})
}
function findElementsWithShadowRoot() {
function hasShadowRoot(element) {
return element.shadowRoot !== null;
}
function traverseTree(node) {
if (hasShadowRoot(node)) {
elementsWithShadowRoot.push(node);
}
const children = node.children || [];
for (let i = 0; i < children.length; i++) {
traverseTree(children[i]);
}
}
const elementsWithShadowRoot = [];
traverseTree(document.body);
return elementsWithShadowRoot;
}
function links(anylink, link, visited, hover, active) {
style(`
${anylink} { outline: solid 1px; }
${link} { color: blue; }
${visited} { color: fuchsia; }
${hover} { color: red; }
${active} { color: yellow; }
`);
}
links('a:any-link , a:any-link *',
'a:link , a:link *',
'a:visited , a:visited *',
'a:hover , a:hover *',
'a:active , a:active *'
);
<div id="host"></div>
<span>I'm not in the shadow DOM <a href='#'>link</a></span>
<br />