尽管这段代码仿佛够用了,而且也达到了目的。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。