• 注册
    • 推荐
    • 查看作者
    • 深入浅出Tampermonkey第二章:编写第一个油猴脚本 Hello world

      2.1. Hello World

      我们步入 Tampermonkey 美妙世界的万里长征将从第一步开始,所有读过技术手册的读者都会很熟悉这一步:让您的电脑打出“Hello world”。

      例 2.1. helloworld.user.js

      // Hello World! example user script
      // version 0.1 BETA!
      // 2005-04-22
      // Copyright (c) 2005, Mark Pilgrim
      // Released under the GPL license
      // http://www.gnu.org/copyleft/gpl.html
      //
      // --------------------------------------------------------------------
      //
      // This is a Greasemonkey user script.
      //
      // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
      // Then restart Firefox and revisit this script.
      // Under Tools, there will be a new menu item to "Install User Script".
      // Accept the default configuration and install.
      //
      // To uninstall, go to Tools/Manage User Scripts,
      // select "Hello World", and click Uninstall.
      //
      // --------------------------------------------------------------------
      //
      // ==UserScript==
      // @name          Hello World
      // @namespace     http://diveintogreasemonkey.org/download/
      // @description   example script to alert "Hello world!" on every page
      // @include       *
      // @exclude       http://diveintogreasemonkey.org/*
      // @exclude       http://www.diveintogreasemonkey.org/*
      // ==/UserScript==
      alert('Hello world!');

      正如您所见到的,这个Hello World脚本的大部分都是注释。有些注释,比如如何安装,没什么特殊含义;那只是对初学者的一些指导。但是,有一节注释确实有特殊含义,下一节会有详细的解释。

      要看到脚本的效果,您首先要安装,然后访问一个不在diveintogreasemonkey.org域名下的网站(例如,Google)。这个页面将会像平时一样显示出来,还会弹出一个对话框:“Hello world!”

      下载

      2.2. 用元数据描述您的用户脚本

      每个用户脚本都含有一段元数据,用来向 Greasemonkey 描述这个脚本自身的信息:发行者,执行规则等等。

      例 2.2. Hello World 元数据

      // ==UserScript==
      // @name          Hello World
      // @namespace     http://diveintogreasemonkey.org/download/
      // @description   example script to alert "Hello world!" on every page
      // @include       *
      // @exclude       http://diveintogreasemonkey.org/*
      // @exclude       http://www.diveintogreasemonkey.org/*
      // ==/UserScript==

      这里有六条独立的元数据信息,作为一个整体包含在注释中。现在让我们按顺序逐条解释。首先讲最外面的这层包装。

      // ==UserScript==
      //
      // ==/UserScript==

      上述标记很重要,必须完全吻合。Greasemonkey 用它们来标记用户脚本的元数据段。这段注释可以放在用户脚本的任何部位,但经常会放在靠近顶部的地方。 
      在元数据段内,第一项是名字。

      // @name          Hello World1

      这是您的用户脚本的名字。它将会在您第一次安装脚本时在安装对话框(install dialog)中显示出来。之后会显示在“管理用户脚本”对话框中。这个名字应该言简意赅。

      @name可选的。如果存在,它只能被定义一次。如果不存在,将会默认显示用户脚本的去掉扩展名.user.js的文件名。

      下一个是命名空间(namespace)。

      // @namespace     http://diveintogreasemonkey.org/download/1

      这是一个 URL,Greasemonkey 用它来区分名称相同但是作者不同的用户脚本。如果您有一个域名,您可以使用它作命名空间。另外您也可以用 tag: URI

      @namespace是可选的。如果存在,它只能被定义一次。如果不存在,将会默认使用下载用户脚本的网站域名。

      元数据可以以任意次序排列。推荐使用@name,@namespace,@description,@include,最后是@exclude,但是其它的顺序也没关系。

      下一项是描述。

      // @description   example script to alert "Hello world!" on every page1

      这是关于用户脚本功能的描述。在您第一次安装脚本时,它将会在安装对话框中显示,之后会在“管理用户脚本”对话框中显示。描述不应多于两句。

      @description 是可选的。如果使用它,那么它只能被定义一次。如果不使用,默认会显示为空白。

      [重要] 
      不要忘记写@description。即使您所写的用户脚本是给自己用的。你最后很可能会拥有很多脚本,如果没有描述的话,在“管理用户脚本”对话框中管理脚本将会成为一件令人头疼的事。

      下面三行是最重要的 (从 Greasemonkey 的角度来看):@include和@exclude URL。

      // @include       *
      // @exclude       http://diveintogreasemonkey.org/*
      // @exclude       http://www.diveintogreasemonkey.org/*

      这几行让 Greasemonkey 知道在那些网站上执行您的用户脚本。您可以明确的指定一个 URL,或者用通配符 来代替域名或路径中的部分字符。在这个例子中,我们告诉 Greasemonkey 在除了 

       网站链接

      和 

       网站链接

      的所有网站上执行。排除(Excludes)优先于包含(includes),所以即使 

       网站链接

      匹配 * (所有网站),它还是会被排除掉,因为它还匹配 

       网站链接*

      @include和 @exclude 是可选的,可以自定义执行和豁免的 URL,但必须每条规则各占一行。如果您没有任何定义, Greasemonkey 将会对所有的网站执行您的用户脚本。(等同于 @include *)。

      [注意] 
      您需要定义非常精确的@include和@exclude元数据。Greasemonkey 不会对域名作任何的假设,如果一个网站符合

       网站链接

       网站链接

      ,您需要把这两个网址都标示出来。

      参考资料

      2.3. 编写用户脚本代码

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

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

      alert('Hello world!');1

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

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

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

      参考资料

      1. Javascript 中的匿名函数

      2. Block Scope in Javascript

      3. associated discussion thread

      2.4. 保存用户脚本

      对于脚本的作者来讲,“管理用户脚本”对话框有个很实用的功能:编辑按钮可以“动态的(live)”修改已安装的脚本。 
      修改/编辑完脚本文件后,点击保存按钮,脚本文件就自动加载到油猴里面。 

      这时候打开新网页,就会弹出hello world对话框。 

    • 14
    • 9
    • 1
    • 599
    • #油猴学院油猴脚本编写
    • 0
      KAIGE初级会员
      转发了
    • 0
      feioo初级会员
      感谢分享,不错的教程
    • 0
      大门悲凉初级会员
      打赏了22金币。
    • 0
      老黑高级会员VIP1首席运营官
      看起来不难
    • 0
      老黑高级会员VIP1首席运营官
      打赏了88金币。
    • 0
      小冰棍初级会员
      谢谢楼主分享
    • 0
      流沙美好初级会员
      真是厉害 良心作品
    • 0
      粗犷就鸡翅初级会员
      感谢分享,好好学习
    • 0
      初级会员
      板凳
    • 单栏布局 侧栏位置: