将Greasemonkey / Tampermonkey / userscript应用于iframe?

问题描述 投票:13回答:3

标题几乎是一个问题:

是否可以将一个Greasemonkey脚本添加到iframed网站?

如果是这样,怎么样?

谢谢。

iframe greasemonkey userscripts tampermonkey
3个回答
16
投票

在Greasemonkey(以及Tampermonkey和大多数用户脚本引擎)中,如果脚本符合@include@exclude和/或@match指令,则会自动触发iframe。 而且,一个流行的问题是how to stop Greasemonkey from firing on iframes

所以,如果您的脚本匹配如下:

@match https://fiddle.jshell.net/*

它会触发jsFiddle“输出”页面,无论它们是否出现在iframe中。


如果您想触发JUST 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.
}

Important:

随着Greasemonkey 4, iframes handling is severely crippled的发布(以及许多其他事情被打破,除此之外)。 它仍然适用于Tampermonkey,Violentmonkey和几乎所有其他用户脚本引擎。 强烈建议您(including by Greasemonkey itself)不要使用Greasemonkey 4或更高版本。


2
投票

对于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属性,这样我们就不会再次触发。


0
投票

请注意,如果您为用户制作了Chrome扩展程序,则还需要将"content_scripts": [ { "matches": ["*://*/*"], "all_frames": true, "js":["dont.js"], "run_at":"document_start" } ] 添加到清单中,否则您的扩展程序将无法使用iframe。

例:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.