Greasemonkey基础
1、每个用户脚本都含有一段元数据,用来向 Greasemonkey 描述这个脚本自身的信息:发行者,执行规则等等。
元数据可以以任意次序排列。笔者推荐使用@name,@namespace,@description,@include,最后是@exclude,但是其它的顺序也没关系。
// @name HelloWorld // @namespace http://diveintogreasemonkey.org/download/ // @description 描述 // @include * // @exclude http://diveintogreasemonkey.org/* // @exclude http://www.diveintogreasemonkey.org/*
@include URL和@exclude URL最重要,在这个例子中,我们告诉 Greasemonkey 在除了http://diveintogreasemonkey.org/和
http://www.diveintogreasemonkey.org/的所有网站上执行。排除(Excludes)优先于包含
(includes),所以即使http://diveintogreasemonkey.org/download/匹配* (所有网站),它还是会被排除掉,因为它还匹配http://diveintogreasemonkey.org/*
@include和@exclude 是可选的,可以自定义执行和豁免的 URL,但必须每条规则各占一行。
如果您没有任何定义, Greasemonkey 将会对所有的网站执行您的用户脚本。(等同于@include *)。
用户脚本的名字:@name可选的。如果存在,它只能被定义一次。如果不存在,将会默认显示用户脚本的去掉扩展名.user.js的文件名
@namespace是可选的。如果存在,它只能被定义一次。如果不存在,将会默认使用下载用户脚本的网站域名。
2、调试用户脚本-用错误控制台追踪错误-F12
如果用户脚本好似没有正常执行,第一个要检查的地方是错误控制台,那里列出了所有与脚本有关的错误,包括用户脚本在内。
使用Greasemonkey内置函数需要在开头声明
// @grant GM_xmlhttpRequest // @grant GM_log 。。。
3、日志函数GM_log(String msg, [level]),这个函数可以将消息写入错误控制台。level 是可选的,默认值是0。其有效的值有:0 - 信息、1 - 警告、2 - 错误
4、存取持久数据:Greasemonkey 定义了两个函数,GM_setValue 和 GM_getValue,用户脚本就可以存取“私有”数据,并且只有这个用户脚本才能访问。
function GM_setValue(key, value);
function GM_getValue(key, defaultValue);
key 参数是没有固定格式(no fixed format)的字符串。value 可以是字符串,布尔值或者整数。
GM_getValue 的 defaultValue 参数是可选的;如果设置了此参数,当查询的 key 指定的值不存在时返回此默认参数。如果不设置 defaultValue,当查询的 key指定的值不存在时,GM_getValue会返回 undefined。
访问 about:config,然后再过滤器中填 greasemonkey.scriptvals ,就可以查看已存储的配置值。
5、GM_xmlhttpRequest — 进行任意的HTTP请求,共7个参数
例子:下面的代码从http://greaseblog.blogspot.com/获取 Atom feed,然后用警告窗口显示结果。
GM_xmlhttpRequest({ method: 'GET', url: 'http://greaseblog.blogspot.com/atom.xml', headers: { 'User-agent': '...', 'Accept': 'application/atom+xml,application/xml,text/xml',}, onload: function(responseDetails) { alert('Request for Atom feed returned ' + responseDetails.status +' ' + responseDetails.statusText + '\n\n' +'Feed data:\n' + responseDetails.responseText); } });
method:字符串,请求使用的方法 HTTP。必需。 通常使用 GET,但也可使任一个 HTTP动词,包含 POST, PUT 和 DELETE。
url:字符串,请求使用的 URL。必需。
headers:这个请求包含的 HTTP 头的关联数组。可选,默认为空字符串。例如:
headers: {'User-Agent': 'Mozilla/4.0 (compatible) Greasemonkey','Accept': 'application/atom+xml,application/xml,text/xml'}
data:字符串,HTTP 请求的主体。可选,默认是空字符串。如果您在模拟提交表单(method == 'POST'),在 headers 域中必需有 Content-type,值为 'application/x-www-form-urlencoded',而且在 data 域包含有 URL 编码后的表单数据。
onload回调:函数对象,请求成功完成调用的回调函数。
onload的回调函数,有一个变量,responseDetails。function onloadCallback (responseDetails);responseDetails 是有五个域的对象。
status:整数,HTTP 应答的状态代码。200 意为请求正常完成。
statusText:字符串,HTTP 状态文字。状态文字是依赖于服务器的。
responseHeaders:字符串,应答包含的 HTTP 头部。
responseText:字符串,应答的主体。
readyState:未使用
onerror回调:函数对象,执行请求发生错误时调用的回调函数。
onerror的回调函数,有一个参数,responseDetails。function onerrorCallback(responseDetails);responseDetails是有五个域的对象。
status:整数,HTTP 的错误代码。404 意为页面无法找到。
statusText:字符串,HTTP 状态文字。状态文字是依赖于服务器的。
responseHeaders:字符串,应答包含的 HTTP 头部。
responseText:字符串,应答的主体。HTTP 错误页面的主体是依赖于服务器的。
readyState:未使用
onreadystatechange回调:函数对象,请求进行时反复调用的回调函数。
onreadystatechange的回调函数,当请求正在进行时反复调用。有一个参数,responseDetails。function onreadystatechangeCallback (responseDetails)
responseDetails 是有五个域的对象。responseDetails.readyState指示了请求当前所在的阶段。
status:整数,应答的 HTTP 状态代码。当 responseDetails.readyState < 4时,这个值是0。
statusText:字符串,HTTP 状态文字。当 responseDetails.readyState < 4时,这个值是空字符串。
responseHeaders:字符串,应答包含的 HTTP 头。当 responseDetails.readyState < 4时,这个值是空字符串。
responseText:字符串, 应答的主体。当 responseDetails.readyState < 4时,这个值是空字符串。
readyState:整数,表示HTTP request请求到了哪个阶段。
1,正在载入。请求已准备好。
2,已加载。请求准备发送到服务器,但是还什么都没发。
3,交互状态。请求已经发送,并且客户端等待服务器完成发送数据。
4。完成。请求已完成,并且其他域中的所有应答数据已可用。
6、GM_openInTab—在新标签中打开指定的URL:function GM_openInTab (url);
二、使用当中遇到的问题:
1、延迟调用函数的错误方法
function helloworld() {alert('Hello world!');}
window.setTimeout("helloworld()", 60);
这段代码没有起任何作用;不会弹出提示窗口。如果您打开错误控制台,会看到一个异常:Error: helloworld is not defined.这是因为当延迟结束,开始调用helloworld()时,helloworld函数已经不存在了。
如果您需要引用用户脚本中的变量或者函数,应该显式的把它们定义为window对象的属性,它是始终存在的。
window.helloworld = function() { //显式的把它们定义为window对象的属性
alert('Hello world!');
}
window.setTimeout("helloworld()", 60)
然而,在 window上设置属性依然不太理想;这有点像用全局变量来做局部变量该做的事。(事实上,就是那么回事,window是全局的,可以被页面中的所有脚本访问。更实际的讲,它可能会与页面自身的脚本,甚至是其它的用户脚本相互干扰。
最佳的解决方案是定义匿名函数,把它作为第一个参数传递给 window.setTimeout。
延迟调用函数的最好方法:
window.setTimeout(function() { alert('Hello world!') }, 60);
我在这里所做的是建立一个没有名字的函数(一个“匿名函数”),然后直接把它传递给 window.setTimeout。这样可以完成与上个例子相同的事,而不会留下痕迹。例如不会被其它的脚本检测到。
我发现我在写用户脚本时经常使用匿名函数。它们很适合创建“一次性”函数,然后当作参数传递给类似window.setTimeout,document.addEventListener 或者赋值给事件句柄像click 或 submit。
2、对于许多网站,无论是否有 www. 前缀,访问网站都是等效的。如果要为这样的站点写用户脚本,需要能匹配这两种地址。
例:匹配域名和它所有子域名的元数据标签 // ==UserScript== // @include http://example.com/* // @include http://*.example.com/* // ==/UserScript==
3、脚本中使用了jQuery代码,而有些网站自己不加载jQuery会导致脚本无法运行,解决办法:自己在脚本中引入@require jQuery
// @require http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js

浙公网安备 33010602011771号