2.3. 编写用户脚本代码

我们的第一个用户脚本是在执行时简单地显示一条提示信息:“Hello world!”。

例 2.3. 显示“Hello world!”提示信息

alert('Hello world!');

尽管这段代码仿佛够用了,而且也达到了目的。Greasemonkey 实际上在幕后做了很多的事情来确保用户脚本不会与页面所包含的原有脚本发生严重的冲突。特别是它会自动的把您的用户脚本封装在一个匿名的函数包里。一般情况下,您可以忽视,但是终究有一天会让您遇到麻烦。所以最好现在就了解一下。

最经常遇到的麻烦之一是在用户脚本里定义的变量和函数能被别的脚本访问。事实上,只要用户脚本运行完了,所有的变量和函数就都不能使用了。如果您期望使用 window.setTimeout 函数,或者在链接挂上字符串式的 onclick 属性然后期望 Javascript 稍后调用您的函数,那么您会遇到问题。

例如,下面这个用户脚本中定义了一个函数 helloworld, 然后尝试设置一个计数器来在一秒后调用这个函数。

例 2.4. 延迟调用函数的错误方法

function helloworld() {
alert('Hello world!');
}

window.setTimeout("helloworld()", 60);

这段代码没有起任何作用;不会弹出提示窗口。如果您打开错误控制台,会看到一个异常:Error: helloworld is not defined.这是因为当延迟结束,开始调用helloworld()时,helloworld函数已经不存在了。

如果您需要引用用户脚本中的变量或者函数,应该显式的把它们定义为window对象的属性,它是始终存在的。

例 2.5. 延迟调用函数的更好方法

window.helloworld = function() {
	alert('Hello world!');
	}

window.setTimeout("helloworld()", 60);

目的达到了!页面完成加载一秒后,一个提示框骄傲的弹了出来,写着:“Hello world!

然而,在 window上设置属性依然不太理想;这有点像用全局变量来做局部变量该做的事。(事实上,就是那么回事,window是全局的,可以被页面中的所有脚本访问。更实际的讲,它可能会与页面自身的脚本,甚至是其它的用户脚本相互干扰。

最佳的解决方案是定义匿名函数,把它作为第一个参数传递给 window.setTimeout

例 2.6. 延迟调用函数的最好方法

window.setTimeout(function() { alert('Hello world!') }, 60);

我在这里所做的是建立一个没有名字的函数(一个“匿名函数”),然后直接把它传递给 window.setTimeout。这样可以完成与上个例子相同的事,而不会留下痕迹。例如不会被其它的脚本检测到。

我发现我在写用户脚本时经常使用匿名函数。它们很适合创建“一次性”函数,然后当作参数传递给类似window.setTimeoutdocument.addEventListener 或者赋值给事件句柄像 clicksubmit

← 用元数据描述您的用户脚本
修改用户脚本 →