当前位置: 首页 > 面试题库 >

从Chrome上的Greasemonkey脚本向页面中注入JS函数

高晋
2023-03-14
问题内容

我有一个Greasemonkey脚本,可以在Firefox和Opera中正常工作。但是,我很难使它在Chrome中工作。问题是将一个函数注入页面,该函数可以由页面中的代码调用。到目前为止,这是我正在做的事情:

首先,我获得了针对Firefox的unsafeWindow的帮助程序参考。这使我可以为FF和Opera(和Chrome,我认为)具有相同的代码。

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

接下来,我将一个函数注入页面。它实际上只是一个非常薄的包装器,除了在我的GM脚本的上下文中调用相应的功能外,什么也不做:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

然后,在我的脚本中有相应的功能:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

最后,我将一些HTML注入到页面中,并带有一个调用该函数的链接。

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);

总结一下:在Firefox中,当用户单击注入的链接时,它将在unsafeWindow上执行函数调用,然后触发超时,该超时将在我的GM脚本的上下文中调用相应的函数,然后进行实际处理。(如果我错了,请纠正我。)

在Chrome中,我仅收到“ Uncaught ReferenceError:未定义setConfigOption”错误。实际上,在控制台中输入“
window.setConfigOption”会产生“未定义”。在Firebug和Opera开发者控制台中,该功能就在那里。

也许有另一种方法可以执行此操作,但是我的一些函数是由页面上的Flash对象调用的,我认为这使我有必要在页面上下文中使用函数。

我快速浏览了Greasemonkeywiki上unsafeWindow的替代方案,但它们看上去都很难看。我是在这里完全走错了路还是应该更仔细地研究这些?

为了使该hack的额外丑陋更容易忍受,我现在至少可以放弃使用unsafeWindow和wrappedJSObject。

我仍然没有设法使Greasemonkey Wiki的内容范围运行器正常工作。它应该做同样的事情,看起来似乎执行得很好,但是<a>例如,页面中的元素永远无法访问我的函数。我还没有弄清楚为什么会这样。


问题答案:

与Chrome中运行在页面上的代码进行通信的唯一方法是通过DOM,因此您必须使用黑客手段,例如<script>在代码中插入标签。请注意,如果您的脚本需要先运行页面上的所有其他内容,则这可能会引起问题。

编辑: 这是NiceAlert扩展程序执行此操作的方式:

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);


 类似资料:
  • 问题内容: 我完全不熟悉Greasemonkey,JavaScript,实际上是所有UI东西。 要求:页面加载后,用户脚本由GS运行一次。但是,我需要多次运行同一脚本而不刷新 用例:例如,Amazon.com搜索使用Ajax进行。我需要在搜索结果中嵌入自定义元素。 每次在同一页面上进行搜索时,我都需要将内容和结果一起注入到search-results-div中(没有页面刷新) 我当前的脚本仅在页面

  • 问题内容: 我正在处理用户脚本,但我发现当主页发出AJAX请求时,该脚本未运行。 有什么方法可以在主页加载和AJAX请求上触发用户脚本? 问题答案: 在AJAX请求上重新运行脚本代码的明智方法是,专注于页面的关键部分并检查更改。 例如,假设页面包含如下所示的HTML: 并且您希望脚本对每个注释进行处理。 现在,您 可以 拦截所有AJAX调用, 或者侦听 (不建议使用)或使用s,但是这些方法可能会变

  • 我必须将MathJax功能添加到我的应用程序中。 根据一些示例,要添加的正确脚本是 脚本从Asset目录中的本地文件夹加载。 当从文件系统上的另一个文件夹(私有应用文件夹)加载到Android WebView中时,我必须将该脚本添加到本地超文本标记语言文件中。 HTML页面中有数学公式,必须由MathJax函数读取。 在加载之前,我无法将脚本作为标记注入HTML文件。但是,公式的渲染也必须在加载后

  • 我试图使div内容不流过页脚,我希望内容div随着页面的展开而展开,但是当文本流过页脚时,它会导致页脚在页面上向上跳转 html,body{margin:0;/top,right,bottom,left/padding:0;/top,right,bottom,left/height:100%;}

  • 问题内容: 我正在尝试让我的Chrome扩展程序在加载新页面时运行该功能,但是在尝试了解如何执行此操作时遇到了麻烦。据我了解,我需要在background.html中执行以下操作: 使用来检查时,页面变更 使用运行的脚本。 这是我的代码: 我还想知道init()函数是否可以访问位于其他JS文件中的其他函数? 问题答案: Chrome扩展程序中的JavaScript代码可以分为以下几类: 扩展代码-

  • 问题内容: 亲爱的所有人,我尝试过CSS位置:固定属性,但是它在Firefox和IE(适用于IE6的hack)上可以正常工作,但对于Chrome则根本不起作用。我以为Chrome是最新的,将非常容易地支持它,但事实并非如此。我尝试了, 再次在IE和Firefox中运行,但在Chrome中出现了问题。请任何人对此有替代解决方案。 问题答案: 这是我使用的代码。注意我将html和正文高度都设置为100