标题几乎是一个问题:
是否可以将一个Greasemonkey脚本添加到iframed网站?
如果是这样,怎么样?
谢谢。
在Greasemonkey(以及Tampermonkey和大多数用户脚本引擎)中,如果脚本符合@include,@exclude和/或@match指令,则会自动触发iframe。 而且,一个流行的问题是how to stop Greasemonkey from firing on iframes。
所以,如果您的脚本匹配如下:
@match https://fiddle.jshell.net/*
它会触发jsFiddle“输出”页面,无论它们是否出现在iframe中。
然后你会检查window.self
财产。
例如,假设您有一个目标页面,如:
<body>
<h1>I'm some webpage, either same-domain or not.</h1>
<iframe src="//domain_B.com/somePath/somePage.htm">
...
然后你可以使用如下脚本:
// ==UserScript==
// @name _Fires specially on domain_B.com iframes
// @match *://domain_B.com/somePath/*
// ==/UserScript==
if (window.top === window.self) {
//--- Script is on domain_B.com when/if it is the MAIN PAGE.
}
else {
//--- Script is on domain_B.com when/if it is IN AN IFRAME.
// DO YOUR STUFF HERE.
}
随着Greasemonkey 4, iframes handling is severely crippled的发布(以及许多其他事情被打破,除此之外)。 它仍然适用于Tampermonkey,Violentmonkey和几乎所有其他用户脚本引擎。 强烈建议您(including by Greasemonkey itself)不要使用Greasemonkey 4或更高版本。
对于iframe
无法触发@include
或@match
的情况,这是一个解决方案。
这适用于Greasemonkey 4。
我们必须等待每个帧加载才能进行操作。我通过使用waitForKeyElements.js
执行此操作,document.querySelectorAll("selector")
等待与给定CSS选择器匹配的元素,就像循环遍历// ==UserScript==
// @include https://blah.example.com/*
// @require https://git.io/waitForKeyElements.js
// ==/UserScript==
function main(where) {
// do stuff here with where instead of document
// e.g. use where.querySelector() in place of document.querySelector()
// and add stylesheets with where.head.appendChild(stylesheet)
}
main(document); // run it on the top level document (as normal)
waitForKeyElements("iframe, frame", function(elem) {
elem.removeAttribute("wfke_found"); // cheat wfke's been_there, use our own
for (let f=0; f < frames.length; f++) {
if (!frames[f].document.body.getAttribute("been_there")) {
main(frames[f].document);
frames[f].document.body.setAttribute("been_there", 1);
}
}
});
中的匹配一样,然后将给定函数应用于响应:
iframe
请注意,所选元素只是一个占位符,表示已加载waitForKeyElements
。我们从iframe
删除了“到那里”跟踪器,因为框架可能会在以后再次加载(我们不能只使用那个body
,因为它的内容被加载到别处)。
当我们知道一个框架已经加载时,我们遍历每个框架并查找我们的标记,框架的been_there
中的HTML属性称为<body been_there="1">
(如main()
)。如果它丢失了,我们可以在框架的文档上运行我们的been_there
函数。当我们完成后,我们添加"all_frames": true
属性,这样我们就不会再次触发。
请注意,如果您为用户制作了Chrome扩展程序,则还需要将"content_scripts": [
{
"matches": ["*://*/*"],
"all_frames": true,
"js":["dont.js"],
"run_at":"document_start"
}
]
添加到清单中,否则您的扩展程序将无法使用iframe。
例:
qazxswpoi