小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
环境准备
油猴插件下载站点,该站点最大的优点就是不用翻墙、不用关注公众号,可以直接下载各种常用的插件,比如 ADBlock Plus,FE-Helper,vue-devtools 等等
当然,坏消息是该网站吧 f12 给干了,我不是那样的人,防啥呢😒
插件安装
插件管理页面
然后吧下载的插件扔进去,点击安装确认就行
新增脚本
脚本分析
基于新建的脚本,可以发现,开头用行注释声明的注释内容,会被油猴解析为相关的参数
我们在 // ==UserScript== 和 // ==/UserScript== 中间,添加行注释,后面接上需要的注解以及属性值,这些数据用于定义脚本的信息,这些数据笼统的称为元数据块
我们需要编写的业务逻辑,建议放在行注释 // ==/UserScript== 后边
元数据块详解
有的注解会需要多个值,我们可以另起一行来赋新值,示例如下:
// @include http://www.example.com/a
// @include http://www.example.com/b
支持赋予多个值的注解有如下这些:
@exclude
@grant
@include
@match
@require
@resource
@description
简短的描述这个脚本可以实现哪些功能
@include
现在提供了类似功能的注解 @match,但会更加安全(指对通配符 * 的处理更加严格)
@match
这个脚本可以匹配哪些 url,指在哪些 url 下会自动运行;如果不指定,将不会运行在任何站点下
// @include http://www.example.com/*
// @include http://*
// @include *
@exclude
指在 @include 或 @match 中匹配的 url 中,需要排除掉哪些不需求匹配的 url
@grant
油猴提供了一些高级 API,这些方法不可以直接在脚本里使用,必须使用 @grant 声明才能使用对应的方法
// @grant GM.getValue
// @grant GM.setValue
@icon
指定一个图片的 url,用于在脚本管理列表页面显示的图标,尺寸建议 32x32
@name
脚本的名称
@namespace
脚本的命名空间,建议用自己的域名或自己的git域名,再加上项目名来做区别,需要确保独一无二
@noframes
当出现时,该命令将限制脚本的执行。该脚本将只在顶级文档中运行,而不会在嵌套框架中运行。它不需要参数,要么存在,要么不存在。默认情况下,允许脚本在框架中运行。
@require
帮助我们引入额外的在线的 js 文件,比如我最喜欢的 jq,操作 dom 一把梭哈
当我们需要引入的多个 js 文件全部加载完成后,才会运行后面的函数主体
@resource
引入外部的资源,并指定唯一的别名,后续使用 GM.getResourceUrl(别名) 直接使用定义的资源
// @resource resourceName http://www.example.com/example.png
@run-at
定义脚本的运行时机
document-end
默认使用此值,当文档主体加载完成,但其他资源(css,js,imgage等)还未就绪时,执行脚本
document-start
脚本将在任何文档开始加载之前运行,因此在任何脚本运行或图像加载之前运行。
document-idle
脚本将在页面和所有资源(图像、样式表等)加载并运行页面脚本之后运行。
@version
定义脚本的版本信息
高级 API
GM 对象中,除了 GM.info() 之外,其他的如果需要使用,必须通过 @grant 进行授权
GM.info
返回当前脚本的详细数据
let info = GM.info();
GM.setValue
允许用户脚本作者跨页面加载和起源持久保存简单值,值类型仅限于数字、布尔、字符串
GM.setValue('key', 'value');
GM.getValue
此方法检索一个用 GM.setValue 设置的值。会返回一个 Promise 对象
let val = await GM.getValue('key');
GM.deleteValue
此方法从存储中删除现有的名称/值对。返回一个被标记为 resolve 或 reject 的 Promise 对象,但不会有值
let result = await GM.deleteValue('key'); // null
GM.listValues
此方法检索此脚本已存储的首选项名称数组。返回一个 Promise 对象,解析得到一个字符串的数组
这个方法或者变更为 GM.listKeys() 更为合适
let keys = await GM.listValues();
GM.getResourceUrl
使用 @resource 定义的图片资源+变量名,可以在函数中通过此方法选择变量名来引用
// ==UserScript==
// @name Image resource example
// @resource logo ../icons/laptop.png
// @grant GM.getResourceUrl
// ==/UserScript==
(async function() {
let img = document.createElement("img");
img.src = await GM.getResourceUrl("logo");
document.body.appendChild(img);
})();
GM.notification
使用基础浏览器和操作系统的通知机制向用户显示通知
function GM.notification(text, title, image, onclick) {}
// or
function GM.notification({
'text': 'str',
'title': 'str',
'image': 'image url',
onclick: function() {},
ondone: function() {}
}){}
GM.openInTab
新开一个标签页
GM.openInTab("http://www.example.com/");
GM.registerMenuCommand
允许用户脚本向用户脚本命令菜单添加一个项。
比如,在脚本中编写 GM.registerMenuCommand('测试标题', ()=>console.log('123')),
/
* @param {String} caption 要显示在菜单项上的标题
* @param {function} commandFunc 当用户选择此菜单项时要调用的函数
* @param {String} accessKey 当菜单打开时,可用于选择命令的单个字符。应该是标题中的一个字母。
*/
function GM.registerMenuCommand(caption, commandFunc, accessKey) {}
GM.setClipboard
设置操作系统剪贴板的当前内容。最常规的做法,用于处理在一些站点上复制内容时,多出的小尾巴
GM.setClipboard('memo');
GM.xmlHttpRequest
这个方法执行与标准的XMLHttpRequest对象类似的功能,仅允许这些请求跨越相同的来源策略边界。
传递的参数有点偏多,具体请参考 文档
或者考虑使用 fetch 替代?
unsafeWindow
这是脚本中的内置实例,等价于浏览器访问的顶层页面的 window 对象
这么详细的开发文档,还不来写2个脚本练练手吗?要是实在不知道咋开头,直接 down 我这个 自动签到 的脚本下来改改就是你自己的好东西~
创作不易,期待大家的鼓励❤~