火狐狸插件油猴Greasemonkey系列一
火狐插件油猴Greasemonkey系列一
油猴Greasemonkey是火狐浏览器user script插件,类似于浏览器端的页面拦截器,对于补充修改增强遗留系统功能有不错的效果。缺点在于插件是安装在浏览器端,部署不是很方便,所以只能是个小众软件。
本系列主要测试油猴插件引用jQuery库的操作。火狐版本25.0,油猴插件版本1.15.1-signed。
引入的两个测试jQuery版本为:页面版本2.2.1,插件版本1.12.1。
新建web项目,测试页面page.html,位于上下文的根部,用户脚本为test.user.js,位于userscripts目录下。
文件结构如图:
测试情形1:page.html没有引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
page.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>游猴插件测试页面</title> </head> <body> <div id="container"> <button onclick="alert('page button click event:' + $.fn.jquery)">content button</button> </div> <div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div> </body> </html>
test.user.js
// ==UserScript== // @name test // @namespace http://yc.telecomjs.com/gm // @description 油猴jQuery库测试 // @include http://localhost:8080/gm/page.html // @require http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js // @grant none // @version 1.0 // ==/UserScript== console.log($.fn.jquery); $('#container').append('<button id="script_btn">script button</button>'); $('#script_btn').click(function(){ alert('script button click event'); });
经过firebug查看控制台,jQuery版本号能够正确显示,扩充的按钮能够正常显示,单击事件正常,点击页面按钮,显示:page button click event:1.12.1,说明用户脚本的库入侵了页面,要避免这样使用jQuery。
测试情形2:page.html没有引入jquery,元数据@grant unsafeWindow,此时用户脚本运行于沙盒中:
修改 test.user.js中的@grant none为@grant unsafeWindow,测试正常。
测试情形3:page.html中引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
page.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>游猴插件测试页面</title> <script type="text/javascript" src="libs/jquery/jquery-2.2.1.min.js"></script> <script type="text/javascript"> console.log('page jquery:' + $.fn.jquery); $(function(){ $('#page_btn').click(function(){ alert('page button click event:' + $.fn.jquery); }); }); </script> </head> <body> <div id="container"> <button id="page_btn">content button</button> </div> <div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div> </body> </html>test.user.js
// ==UserScript== // @name test // @namespace http://yc.telecomjs.com/gm // @description 油猴jQuery库测试 // @include http://localhost:8080/gm/page.html // @require http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js // @grant none // @version 1.2 // ==/UserScript== console.log('user script jquery:' + $.fn.jquery); $('#container').append('<button id="script_btn">script button</button>'); $('#script_btn').click(function(){ alert('script button click event:' + $.fn.jquery); });
经过测试:
console输出:
page jquery:2.2.1
user script jquery:1.12.1
点击content button,输出:page button click event:1.12.1
点击script button,输出:script button click event:1.12.1
这个测试结果说明:用户脚本在页面所有脚本执行完成后执行,所以console的jQuery版本是2.2.1,脚本引入jQuery会替换页面的jQuery,原因在于jQuery中有将$和jQuery赋值给window.$ 和 window.jQuery的操作,@grant none的情形下,window等于unsafeWindow,脚本的jQuery就替代了页面jQuery,在不同版本下的jQuery,有可能会导致页面原始功能异常,所以要特别小心,下面是两种安全的情形。
测试情形4:page.html引入jquery,元数据@grant unsafeWindow,此时用户脚本运行于沙盒中:
将情形3中的@grant none修改为@grant unsafeWindow
此时测试结果:
console输出:
page jquery:2.2.1
user script jquery:1.12.1
点击content button,输出:page button click event:2.2.1
点击script button,输出:script button click event:1.12.1
用户脚本运行在沙盒里面,没有与页面js冲突,可以解决情形3的问题。
测试情形5:page.html中引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
修改情形3的 test.user.js的文件为:
// ==UserScript== // @name test // @namespace http://yc.telecomjs.com/gm // @description 油猴jQuery库测试 // @include http://localhost:8080/gm/page.html // @require http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js // @grant none // @version 1.5 // ==/UserScript== this.$ = this.jQuery = jQuery.noConflict(true); console.log('user script jquery:' + $.fn.jquery); $('#container').append('<button id="script_btn">script button</button>'); $('#script_btn').click(function(){ alert('script button click event:' + $.fn.jquery); });
测试结果同情形4,说明this.$ = this.jQuery = jQuery.noConflict(true);将页面的jQuery版本做了复原。
测试情形6:page.html中未引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
page.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>游猴插件测试页面</title> </head> <body> <div id="container"> <button onclick="alert('page button click event:' + $)">content button</button> </div> <div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div> </body> </html>
test.user.js
// ==UserScript== // @name test // @namespace http://yc.telecomjs.com/gm // @description 油猴jQuery库测试 // @include http://localhost:8080/gm/page.html // @require http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js // @grant none // @version 1.6 // ==/UserScript== this.$ = this.jQuery = jQuery.noConflict(true); console.log('user script jquery:' + $.fn.jquery); $('#container').append('<button id="script_btn">script button</button>'); $('#script_btn').click(function(){ alert('script button click event:' + $.fn.jquery); });console输出:
user script jquery:1.12.1
点击content button,输出:page button click event:undefined
点击script button,输出:script button click event:1.12.1
结果是正常的。
总结,在油猴用户脚本中引入jQuery库,最好运行在沙盒环境下,简单地加一条元数据@grant unsafeWindow即可;如果运行在@grant none情形下,在脚本的顶部一定要添加一条this.$ = this.jQuery = jQuery.noConflict(true);以防止与原页面jQuery库冲突,导致原页面功能异常。
系统二准备测试下用户脚本如何引入bootstrap的css文件方案。