Hen*_*ger 38 javascript greasemonkey google-chrome userscripts google-chrome-extension
我有一个Greasemonkey脚本,在Firefox和Opera中运行良好.但是,我很难让它在Chrome中运行.问题是在页面中注入一个可以通过页面中的代码调用的函数.这是我到目前为止所做的事情:
首先,我得到一个帮助引用Firefox 的unsafeWindow.这让我可以使用相同的FF和Opera代码(我认为是Chrome).
var uw = (this.unsafeWindow) ? this.unsafeWindow : window;
Run Code Online (Sandbox Code Playgroud)
接下来,我在页面中注入一个函数.它实际上只是一个非常薄的包装器,除了在GM脚本的上下文中调用相应的函数之外什么都不做:
uw.setConfigOption = function(newValue) {
setTimeout(setConfigOption, 0, newValue);
}
Run Code Online (Sandbox Code Playgroud)
然后,我的脚本中有相应的功能:
setConfigOption = function(newValue) {
// do something with it, e.g. store in localStorage
}
Run Code Online (Sandbox Code Playgroud)
最后,我在页面中注入一些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);
Run Code Online (Sandbox Code Playgroud)
总结一下:在Firefox中,当用户单击该注入的链接时,它将在unsafeWindow上执行函数调用,然后触发超时,该超时在我的GM脚本的上下文中调用相应的函数,然后执行实际处理.(如果我错了,请纠正我.)
在Chrome中,我只是得到一个"未捕获的ReferenceError:setConfigOption未定义"错误.实际上,在控制台中输入"window.setConfigOption"会产生"未定义".在Firebug和Opera开发人员控制台中,功能就在那里.
也许有另一种方法可以做到这一点,但是我的一些函数是由页面上的Flash对象调用的,我认为这使得我必须在页面上下文中使用函数.
我在Greasemonkey维基上快速浏览了unsafeWindow的替代品,但它们看起来都非常难看.我在这里完全走错了轨道还是应该仔细研究这些?
决议:我跟着Max S. 建议,现在可以在Firefox和Chrome中使用.因为我需要对页面可用的函数必须回调常规函数,所以我将整个脚本移动到页面,即它完全包含在他称为"main()"的函数中.
为了使这个hack的额外丑陋更加可以忍受,我至少可以放弃unsafeWindow和wrappedJSObject的使用.
我还没有设法从Greasemonkey wiki中获取内容范围运行器.它应该做同样的事情似乎执行得很好,但是我的函数永远不会<a>被页面中的元素访问,例如.我还没弄清楚为什么会这样.
Max*_*keh 68
与Chrome中页面上运行的代码进行通信的唯一方法是通过DOM,因此您必须使用hack,例如<script>在代码中插入标记.请注意,如果您的脚本需要在页面上的其他所有内容之前运行,则可能会出现问题.
编辑:这是尼斯警报扩展如何做到这一点:
function main () {
// ...
window.alert = function() {/* ... */};
// ...
}
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
Run Code Online (Sandbox Code Playgroud)
小智 15
我有这个 :
contentscript.js:
function injectJs(link) {
var scr = document.createElement('script');
scr.type="text/javascript";
scr.src=link;
document.getElementsByTagName('head')[0].appendChild(scr)
//document.body.appendChild(scr);
}
injectJs(chrome.extension.getURL('injected.js'));
Run Code Online (Sandbox Code Playgroud)
inject.js:
function main() {
alert('Hello World!');
}
main();
Run Code Online (Sandbox Code Playgroud)
其他答案要么强迫您使用函数表达式,导入外部附加文件,要么使用长时间修补的 hack。
此答案将直接从源代码将 JavaScript 添加到页面中。它将使用 ECMAScript 6 (ES6)模板文字轻松地将多行 JavaScript 字符串放到页面上。
var script = document.createElement('script');
script.type = "text/javascript";
script.innerHTML = `
function test() {
alert(1);
}
`;
document.getElementsByTagName('head')[0].appendChild(script);
Run Code Online (Sandbox Code Playgroud)
``请注意定义多行字符串的开头和结尾的反引号。
| 归档时间: |
|
| 查看次数: |
63305 次 |
| 最近记录: |