2008-09-23 98 views

回答

8

通过GM_setValue(keyname, value)将数据存储为mozilla首选项值,可以在页面加载中持久保存数据。

下面是一个简单的例子,tallys的脚本已经被执行的次数 - 由给定的浏览器:

 
var od = GM_getValue("odometer", 0); 
od++; 
GM_setValue("odometer", od); 
GM_log("odometer=" + od); 

GM值类似于在cookie值的cookie只能由起源访问域,GM值只能由创建它们的脚本访问。

+0

这真的是一个隐藏的功能,甚至鲜为人知?它是Greasemonkey记录的API的一部分,它本身非常小。 – 2008-09-23 14:15:13

+0

同意这本身并不隐藏。但它属于成语范畴。 – 2008-09-23 14:28:35

+0

是的,通用汽车的API真的不是那么大,因此我不知道'隐藏的功能'本身 - 询问有趣的技术/漏洞提供有用的,非显而易见的功能会更有趣。 – 2008-09-23 15:28:54

3

匿名统计

假设你有一个基本的托管服务,提供访问日志,你可以轻松地跟踪您的脚本的基本使用统计信息。

  1. 在您自己的网站上放置一个gif文件(例如,徽标图像)。
  2. 在脚本中,附加一个img元素引用该GIF的页面:现在
 
var img = document.createElement("img"); 
img.src = "http://mysite.com/logo.gif"; 
document.body.appendChild(img); 

,每个用户执行脚本的时候,您的托管服务将注册在该gif文件一击。

要跟踪多个脚本,请为每个脚本使用不同的gif文件。或者在URL中添加某种区分参数(例如:http://mysite.com/logo.gif?zippyver=1.0)。

+3

...当你在它的时候,你也可以发送他们的用户名和密码 – 2008-09-23 14:36:09

+0

请提供代码示例 – 2008-09-23 14:48:12

+0

我实际上有一个脚本,当安装脚本时会生成一个伪GUID, GM_setValue,然后每天*脚本运行它会打我的网站,发送查询字符串中的GUID。我将这些数据记录到数据库中以获取使用情况统计信息。 – 2008-09-23 15:31:33

13

Greasemonkey脚本通常需要搜索页面上的内容。而不是挖掘DOM,尝试使用XPath来定位感兴趣的节点。 document.evaluate()方法允许您提供XPath表达式并返回一组匹配节点。这是一个不错的tutorial让你开始。作为一个例子,这里有一个脚本,我写了导致。中文的帖子链接在新标签中打开(在默认皮肤):

// ==UserScript== 
// @name   New Tab in phpBB3 
// @namespace  http://robert.walkertribe.com/ 
// @description Makes links in posts in phpBB3 boards open new tabs. 
// ==/UserScript== 

var newWin = function(ev) { 
    var win = window.open(ev.target.href); 
    if (win) ev.preventDefault(); 
}; 

var links = document.evaluate(
     "//div[@class='content']//a[not(@onclick) and not(@href='#')]", 
     document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); 

for (var i = 0; i < links.snapshotLength; i++) { 
    var link = links.snapshotItem(i); 
    link.addEventListener("click", newWin, true); 
} 

代码中使用XPath表达式识别所有a要素:1)做没有onclick属性,2)其href属性未设置为"#",以及3)在div的内部找到,其class属性设置为"content"

+1

我想评论说,尽管人们普遍担心XPath可能会比DOM行走的代价太昂贵,但我发现它即使在积极使用时也能立即执行。 – 2008-09-23 15:20:48

10

脚本可以添加图形到一个页面,即使你没有任何地方托管文件,通过数据URI。

例如,这里是一个小按钮图形:

 
var button = document.createElement("img"); 
button.src = "data:image/gif;base64," 
    + "R0lGODlhEAAQAKEDAAAA/wAAAMzMzP///yH5BAEAAAMALAAAAAAQABAAAAIhnI+pywOtwINHTmpvy3rx" 
    + "nnABlAUCKZkYoGItJZzUTCMFACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==" 
somenode.appendChild(button); 

这是一个在线image encoder

wikipedia article关于数据URI标准。

2

一个有用的XPath技术是指定您的匹配相对于您已经找到的节点。至于计算器一个人为的例子:

 
// first we got the username link at the top of the page 
var hdrdiv = document.evaluate(
    "//div[@id='headerlinks']/a[1]", document, null, 
    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 

// now we can retrieve text that follows it, (user's reputation score) 
// (note that hdrdiv is now the contextNode argument, rather than document) 
var reptext = document.evaluate(
    "following-sibling::span", hdrdiv, null, 
    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 

alert("Reputation Score: " + reptext.textContent); 

可以匹配任何相对于contextNode方向,祖先,子孙,以前,以下。 这是一个有帮助的 XPath reference

2

GreaseMonkey脚本在DOM准备就绪时运行,因此您不需要添加onload事件,只需在GreaseMonkey脚本中直接操作DOM即可。

13
==UserScript== 
... 
@require http://ajax.googleapis.com/ajax/framework-of-your/choice.js 
==/UserScript== 
5

GM_setValue通常仅存储32位整数,字符串和布尔值,但是可以利用uneval()方法(和在检索后的eval())来存储任何对象。如果您正在处理纯JSON值(而不是JavaScript对象),请使用JSON.stringify存储并使用JSON.parse进行检索;这将会更快更安全。

var foo={people:['Bob','George','Smith','Grognak the Destroyer'],pie:true}; 
GM_setValue('myVeryOwnFoo',uneval(foo)); 
var fooReborn=eval(GM_getValue('myVeryOwnFoo','new Object()')); 
GM_log('People: '+fooReborn.people+' Pie:'+fooReborn.pie); 

我倾向于使用“新的对象()”作为我在这种情况下默认,但你也可以使用“{}”。请记住,“{}”评估为字符串,而不是对象。像往常一样,小心()。

1

已过时: Firefox在Greasemonkey脚本中用FF版本17取消了对E4X的支持。使用GM_info来获取元数据。


您可以使用E4X访问您的== == UserScript信息作为变量:

var metadata=<> 
// ==UserScript== 
// @name   search greasemonkey 
// @namespace  foo 
// @include  http://*.google.com/* 
// @include  http://*.google.ca/* 
// @include  http://search.*.com/* 
// @include  http://*.yahoo.com/* 
// ==/UserScript== 
</>.toString();