赵迪的妹妹赵鹿言咋了:书写第一个油猴(Greasemonkey)插件

来源:百度文库 编辑:中财网 时间:2024/04/28 00:13:58

书写第一个油猴(Greasemonkey)插件

发布时间:2010/08/29

油猴

油猴插件简介

Greasemonkey是Mozilla Firefox的一个附加组件。它让用户安装一些脚本使大部分HTML为主的网页于用户端直接改变得更方便易用。随着Greasemonkey脚本常驻于浏览器,每次随着目的网页打开而自动做修改,使得运行脚本的用户印象深刻地享受其固定便利性。

大部分Greasemonkey用户脚本都是自行撰写,使用对某网站专用的JavaScript代码,通过文档对象模型(DOM)接口对网页内容做操作。userscripts.org维护了个 Greasemonkey 数据库。该数据库描述哪个网址网页对应到哪个脚本。

当用户加载匹配的网页,Greasemonkey便调用相关的脚本,而该脚本便根据脚本内容改变网页的内容。Greasemonkey脚本亦能通过非网域绑定的XMLHTTP要求来查询外部HTTP资源。Greasemonkey亦遵循某用户名.user.js的格式,这让当该特定用户拜访时 Greasemonkey 可自动侦测并提供安装选项。除了JavaScript代码,Greasemonkey脚本包括有限可选用后数据集。该后数据集描述了脚本名称、脚本描述、网址用来区分同名脚本的地址空间、以及原本该脚本为哪些网址撰写的列表。

油猴官方网站:http://www.greasespot.net/
Firefox的油猴插件安装地址:https://addons.mozilla.org/firefox/748/
油猴平台脚本库:http://userscripts.org/

Firefox用户请先安装油猴插件:。
更多可见:油猴的维基百科

用户脚本

用户脚本(user script)就是一个js 文件,也就是我们要写插件,他通常是xxx.user.js,xxx是文件名,且必须由user.js结尾,当你将脚本拖拽到火狐进行安装时,油猴将自动检测到此文件为油猴插件,弹出安装窗口。

这是名为hello world脚本的安装

插件安装窗口

使用metadata来描述你的插件

每一个插件都有一个metadata区域来告诉油猴关于这个插件的信息,如:插件的来源(@namespace)和插件何时运行(@include)。

eg. hello world metadata

// ==UserScript==// @name          Hello World// @namespace     http://blog.meituo.net/projects/greasemonkey/// @description   example script to alert "Hello world!" on every page// @include       *// @exclude       http://blog.meituo.net/*// @exclude       http://www.meito.22web.net/*// ==/UserScript==

这里metadata有六条独立的条目,包裹在一组特定 Greasemonkey 的注释(Greasemonkey-specific comments)里,让我们按顺序介绍一下,从注释包裹开始

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

这个注释块很重要,而且要严格匹配(成对出现)油猴使用它们来标记metadata的开始和结束,这个注释块可以放在在脚本的任何地方,但是通常放在靠近开头的位置。

@name

在metadata内,第一项是name.

// @name          Hello World

这是插件的名称,当你安装插件时会在安装窗口看到,安装后在 “管理用户脚本” 窗口也可以看到,名字嘛当然要精简,有概况性。
@name 是可选的,也就是可以不用为插件起名字。如果存在,它可能只出现一次。如果不存在,它将默认为用户的脚本文件名减去 .user.js。

@namespace

下一项是 namespace。

// @namespace     http://blog.meituo.net/projects/greasemonkey/

这一项是网址(URL),油猴使用它来区分拥有相同名称但是由不同的开发人员书写的插件,如果你有域名(或者二级域名的等),你可以用它作为namespace,或者你可以使用tag: URI (此链接已坏).
@namespace 也是可选项,如果存在,它可能只出现一次。如果不存在,它将默认为用户的下载该脚本文件的网址。
tip:
你可以使用任意的顺序来书写这些metadata项,我喜欢使用这样的顺序:@name 、@namespace 、@description 、@include 和@exclude ,当然你可以按照自己的方式。

@description

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

这是为了更可读(human-readable),当你安装插件时会在安装窗口看到,安装后在 “管理用户脚本” 窗口也可以看到。其不应长于两句话。
@description 也是可选项,如果存在,它可能只出现一次。如果不存在,默认为空。
impotant:
不要忘记写@description ,即使是为你自己书写脚本,你最终或许会有很多,如果你不书写的话在“管理用户脚本” 窗口将难以管理这些插件。

下一项是是最重要的一项(Greasemonkey 的角度来看),也就是@include 和@exclude URLs

@include 和@exclude

// @include       *// @exclude       http://blog.meituo.net/*// @exclude       http://www.meito.22web.net/*

这一项告知油猴在哪个网站你想使用这个脚本,两者都使用指定一个的 URL,* 作为域的名称或路径的一部分的简单通配符字符。 在这种情况下我们告诉Greasemonkey http://blog.meituo.net/及http://www.meito.22web.net/ 除外的所有站点上执行 Hello World 脚本。 exclude优先级高于include,这样即使 http://blog.meituo.net/download/ 匹配 * (所有站点),因为它也匹配 http://blog.meituo.net/* ,所以http://blog.meituo.net/download/ 将被排除。
@include 和@exclude 也是可选的,你可以书写任意多的@include 和@exclude 的URLs,但是你必须将每一个url写在单独的一行,如果两项都没有写明,油猴将在所有的站点使用这个脚本。(效果等同于 // @include * )
impotant:
对于@include 和@exclude 你需要使用非常清晰的网址,油猴不会对 用户认为相同的网址(URLs)进行任何的联想假设(assumptions),如:如果你想在http://example.com/ 和 http://www.example.com/ 同时使用脚本,必须两个都要声明。

书写脚本

我们的第一个脚本执行时 将简单的弹出 “hello world”。

alert("hello world!");

虽然代码看起来明显足够,执行也完全符合预期,但在幕后 Greasemonkey 其实做很多事情来确保 用户脚本(user scripts)不与页面中的js发生冲突,它自动将 用户脚本封装到一个匿名函数里,通常你可以忽略这一点,但是它最终会给你制造大麻烦,因此现在您也可能学习一下。

例如,该用户脚本定义了一个函数的HelloWorld,然后尝试设置一个计时器在一秒钟后来调用它。

eg:延迟执行一个函数的错误方法

function helloworld(){alert("hello world!");}window.setTimeout("helloworld",60);

这将不会工作,不会弹出窗口,如果你打开JavaScript 控制台,你会发现一个异常,Error: helloworld is not defined. 这是因为通过计时器的执行hellowworld()时helloworld函数已经不存在了
如果你想后来使用你用户脚本中的变量和函数,您将需要显式地将它们定义为始终可用的window对象的属性。

eg:更好的延迟执行函数的方法

window.helloworld =function(){alert("hello world!");}window.setTimeout("helloworld",60);

这个代码得到了预期的效果,页面加载后一秒弹出窗口“hello world!”。
然而将属性加到 window 上也不是一个好选择,这样就有点像本地脚本的全局变量(事实上,它是完全一样的,因为window 是全局的并可以被页面上的所有脚本访问),更实际上,他最终可能会和页面上的脚本冲突或者和别的“用户脚本”冲突。
最好的解决方法就是 你自己定义一个匿名函数并且将它最好的解决办法是定义一个匿名函数,并将它作为window.setTimeout的第一个参数。

eg:最好的 延迟执行函数的方法

window.setTimeout(function(){alert("hello world!")},60);

我这里做的就是创建了一个匿名函数,并将它作为setTimeout的第一个参数,这样和我们上例一样的结果,但是没有留下隐患,它对其他脚本是不可见的。
我在书写用户脚本时通常使用匿名函数。 他们是适合创建”一次性“函数,将它们作为参数传递给 window.setTimeout ,document.addEventListener,或将分配给事件处理程序,如单击或提交。
现在最常用的写法是将将代码写进一个自动执行的闭包:

(functon(){//code goes here})()

编辑用户脚本

对用户脚本作者来说,“管理用户脚本” 窗口有一个好处就是可以随时动态的修改脚本。

当你在“管理用户脚本”窗口编辑代码事,实际上你是在动态的编辑位于火狐 profile 目录下脚本的副本,我有一个习惯就是每次我完成一个脚本的动态测试,就保存一份。

那么最终我们的脚本helloworld.user.js为:

// ==UserScript==// @name          Hello World// @namespace     http://blog.meituo.net/projects/greasemonkey/// @description   example script to alert "Hello world!" on every page// @include       *// @exclude       http://blog.meituo.net/*// @exclude       http://www.meito.22web.net/*// ==/UserScript==alert('Hello world!');

当然我们可以添加一些跟多的信息和介绍

// Hello World! example user script// version 0.1 BETA!// 2005-04-25// 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 it, you need// Greasemonkey 0.3 or later: 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://blog.meituo.net/projects/greasemonkey/// @description   example script to alert "Hello world!" on every page// @include       *// @exclude       http://blog.meituo.net/*// @exclude       http://www.meito.22web.net/*// ==/UserScript==alert('Hello world!');
下载pdf教程下载HTML教程