亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

油猴腳本編寫教程詳解

2024-07-21 02:03:14
字體:
來源:轉載
供稿:網友

油猴腳本(Tampermonkey)是一個非常流行的瀏覽器擴展,它可以運行由廣大社區編寫的擴展腳本,來實現各式各樣的功能,常見的去廣告、修改樣式文件、甚至是下載視頻。今天我們就來看看如何編寫自己的油猴腳本。當然為了運行油猴腳本,你應該在瀏覽器中安裝油猴插件。

安裝油猴插件

安裝油猴插件非常簡單,直接在瀏覽器的擴展商店中安裝即可。國產瀏覽器的話一般可以通過下載擴展文件手動拖動的方式來安裝。下圖是微軟新版Edge瀏覽器的擴展商店,直接搜索Tampermonkey即可。

新建腳本

首先在瀏覽器右上角找到并點擊油猴插件,選擇添加新腳本。

然后就會打開如圖所示的編輯器窗口,我們就可以在其中編輯自己的腳本文件了。如果你喜歡的話,還可以將腳本內容復制到合適的編輯器中編輯,完成之后再復制回來。

如果你點擊開發者菜單的話,可以選擇ES6模板,然后就可以在腳本中使用新版JavaScript的特性了,它會有Babel轉譯回ES5。不過這個模板貌似有點問題,用了它就沒辦法使用代碼糾錯功能了。所以這里我還是選擇了默認的ES5模板。

腳本編寫方法

功能注釋

首先來看看腳本的內容,上面是一大排注釋,這些注釋可以非常有用的,它表明了腳本的各個屬性。下面來簡單介紹一下。

屬性名 作用
name 油猴腳本的名字
namespace 命名空間,類似于Java的包名,用來區分相同名稱的腳本,一般寫成作者名字或者網址就可以了
version 腳本版本,油猴腳本的更新會讀取這個版本號
description 描述,用來告訴用戶這個腳本是干什么用的
author 作者名字
match 只有匹配的網址才會執行對應的腳本,例如 * 、 http://* 、 http://www.baidu.com/*等,參見 谷歌開發者文檔
grant 指定腳本運行所需權限,如果腳本擁有相應的權限,就可以調用油猴擴展提供的API與瀏覽器進行交互。如果設置為 none 的話,則不使用沙箱環境,腳本會直接運行在網頁的環境中,這時候無法使用大部分油猴擴展的API。如果不指定的話,油猴會默認添加幾個最常用的API
require 如果腳本依賴其他js庫的話,可以使用require指令,在運行腳本之前先加載其他庫,常見用法是加載jquery
connect 當用戶使用 GM_xmlhttpRequest 請求遠程數據的時候,需要使用connect指定允許訪問的域名,支持域名、子域名、IP地址以及 * 通配符
updateURL 腳本更新網址,當油猴擴展檢查更新的時候,會嘗試從這個網址下載腳本,然后比對版本號確認是否更新

腳本權限

下面簡單介紹一下grant指令那里可以填寫的一些權限,詳情請查看 油猴腳本文檔 。這里就簡單介紹幾個常用的,可以調用的函數全部以GM_作為開頭。

權限名 功能
unsafeWindow 允許腳本可以完整訪問原始頁面,包括原始頁面的腳本和變量。
GM_getValue(name,defaultValue) 從油猴擴展的存儲中訪問數據??梢栽O置默認值,在沒成功獲取到數據的時候當做初始值。如果保存的是日期等類型的話,取出來的數據會變成文本,需要自己轉換一下。
GM_setValue(name,value) 將數據保存到存儲中
GM_xmlhttpRequest(details) 異步訪問網頁數據的API,這個方法比較復雜,有大量參數和回調,詳情請參考官方文檔。
GM_setClipboard(data, info) 將數據復制到剪貼板中,第一個參數是要復制的數據,第二個參數是MIME類型,用于指定復制的數據類型。
GM_log(message) 將日志打印到控制臺中,可以使用F12開發者工具查看。
GM_addStyle(css) 像網頁中添加自己的樣式表。
GM_notification(details, ondone), GM_notification(text, title, image, onclick) 設置網頁通知,請參考文檔獲取用法。
GM_openInTab(url, loadInBackground) 在瀏覽器中打開網頁,可以設置是否在后臺打開等幾個選項

還有一些API沒有介紹,請大家直接查看官方文檔吧。

編寫腳本

編寫腳本就很簡單了,編寫到 // Your code here .. 那里即可??梢跃帉懞瘮担缓笤谧詈笳{用這幾個函數,這樣的模塊化編寫方法寫出來的腳本比較容易維護。

等vagrant更新時候提醒我的腳本

前段時間了解了vagrant這個東西,感覺很有意思,準備研究一下,但是照著官網教程運行的時候,第一步就發生了錯誤。我上網一搜,原來我更新的virtualbox比較新,vagrant恰好不支持。但是如今幾個月過去了,vagrant還是沒有更新,所以我要寫一個腳本,等到vagrant更新的時候,給我網頁上彈出一個對話框。

首先訪問 vagrant官網 ,然后就可以看到中間下載按鈕上大大的版本號2.2.6了。因為版本肯定是不會倒退的,所以只要判斷一下版本號不是2.2.6,就可以彈出提示了。通過F12開發者工具可以看到,這三個按鈕其實都是鏈接,只不過顯示成了按鈕的樣子,而且他們恰好都位于 header 標簽之中。如果如果可以的話,直接用選擇器就可以非常輕松的獲取到版本號。

為了能在更新的時候及時獲取到提示,我需要腳本在所有網站上生效,來檢測版本。但是這樣做會導致另外一個問題,那就是每次打開一個網頁都會運行一次檢查vagrant的腳本,而這是完全不必要的。所以需要一個額外的判斷,這就需要利用油猴提供的API來保存當前日期,只有每天第一次的時候才會執行檢查代碼。本來我想的很復雜,需要一個日期變量,然后還要額外一個變量保存是否是今天第一次更新。后來我發現我想的太多了,做法其實很簡單。每天先獲取一次日期,然后和事先保存的日期比較,如果不一樣的話才執行腳本,并將日期設置為今天的日期;如果日期一樣的話無事發生。

最后一個問題就是如何來判斷版本號,有兩種方法:第一種就是上面提到的,直接解析HTML代碼并找到版本號;第二種是更直接的辦法, 因為vagrant也是Github上開源的項目,所以可以直接調用Github的API來獲取最新發布的版本號??上У氖?,第二種辦法我試了一下居然不成功,不知為何,沒辦法獲取到發布信息,但是換成其他項目就可以。所以最后沒辦法只好采用第一種辦法。有興趣的同學可以自己試一下第二種方法。

好了,所有相關的坑我都已經解釋完畢了,相信大家應該很容易就可以看懂下面的代碼,我就不介紹了。雖然看著簡單,但是我其實還是踩了不少的坑,就這點代碼花了我好幾天的時間。而且確實這個代碼寫的也并不是很好,因為ajax取回來的代碼是完整一個html頁面,貌似用原版DOM API沒辦法解析,最后只好用jQuery的 parseHTML 方法解析的。而且我還因為原生方法和jQuery之間的方法名搞混了,浪費了很多時間。

// ==UserScript==// @name remind_me_vagrant_update// @namespace https://github.com/techstay/myscripts// @version 0.1// @description remind me if vagrant support virtualbox// @author techstay// @match *// @require https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js// @connect vagrantup.com// @grant GM_setValue// @grant GM_getValue// @grant GM_setClipboard// @grant GM_log// @grant GM_xmlhttpRequest// @grant unsafeWindow// @grant window.close// @grant window.focus// ==/UserScript==(function () { 'use strict'; const CHECKED_DATE = 'checkedDate'; function checkDateEquals(a, b) { return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); } function checkVagrantVersion() { GM_setValue(CHECKED_DATE, new Date()); GM_xmlhttpRequest({ "method": "GET", "url": "https://www.vagrantup.com/", "headers": { "user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' }, "onload": function (result) { var list = jQuery.parseHTML(result.response); jQuery.each(list, function (i, el) {  if (el.nodeName == 'HEADER') {  var header = jQuery.parseXML(el.innerHTML);  var version = header.getElementsByTagName('a')[1].textContent.replace('Download ', '');  if (version != '2.2.6') {  alert('Vagrant update!');  }  return false;  } }); } }); } var today = new Date(); var lastCheckedDay = new Date(GM_getValue(CHECKED_DATE, new Date('2006-1-1'))); if (!checkDateEquals(lastCheckedDay, today)) { checkVagrantVersion(); }})();

調試腳本

編寫腳本很難一次成功,大部分時間都花在了調試上面。調試油猴腳本的話有幾種調試方法。

第一種方法就是最原始的打印日志,可以利用 console.logGM_log 來將關鍵信息打印出來,上面的腳本就是我靠打印日志一點點發現各種參數錯誤的。說實話這種辦法有點笨。

第二種就是利用瀏覽器的調試功能,在腳本需要調試的地方插入 debugger; 語句,然后在打開F12開發者工具的情況下刷新頁面,就會發現網頁已經暫停在相應位置上。這樣就可以利用F12開發者工具進行單步調試、監視變量等操作了。

將文章同步復制到Csdn和思否編輯器的腳本

我的文章一般都是簡書首發,然后復制粘貼到Csdn中,但是后來我發現每次手動操作太蠢了,為什么不用腳本來自動化呢?所以我又寫了個腳本幫忙完成自動化工作。本來以為這個腳本應該比較簡單,不過還是踩了很多坑才湊合把功能寫出來。

首先是數據的保存,利用油猴提供的 GM_setValue 倒是可以很簡單的將文章標題和內容保存起來。不過問題來了,如何在不同頁面之間共享呢?有幾種方案:第一種最簡單粗暴,直接復制兩份,對應頁面首先判斷是否存在數據,存在的話才執行復制操作,然后清空數據。這種方案最簡單,而且如果自己直接新建文章的話也不會出問題。第二種就是數據只保存一份,通過幾個變量來確定什么時候復制完成,清空數據,但是這樣比較復雜,要理清邏輯順序很麻煩。所以最后我就采用了第一種辦法。

然后又遇到一個問題,那就是如果編輯器自帶了保存和恢復功能,很可能會把我復制過去的文章給覆蓋了,所以需要等頁面加載完之后,延遲一段時間才進行復制操作。然后我又谷歌了一番,差不多解決了這個問題。

然后遇到了一個非常棘手的問題,就是SF的編輯器設計比較復雜,沒辦法通過直接填充 value 或者 text 屬性的方式來寫入文章,我想了很久也沒有想出來怎么解決。沒辦法只好改用剪貼板的方式來糊弄了,也就是將文章內容復制到剪貼板里頭,然后手動粘貼到編輯器中。

最后一個問題就是簡書上這個復制按鈕應該如何實現,其實簡書編輯器的工具欄倒是空了一些部分,我本來想把按鈕直接加到那個上面。但是我發現貌似一旦添加東西,那個工具欄會自動重載取消更改,所以水平所限沒做到,只好利用jQueryUI加了一個很丑的浮動按鈕,而且因為拖動的時候會觸發單擊,沒辦法把按鈕改成了雙擊觸發。

最后的腳本就是下面這樣的。相比第一個腳本多了幾個打開新頁面、刪除變量、訪問剪貼板的API。

// ==UserScript==// @name copy_jianshu_to_csdn_and_segmentfault// @namespace https://github.com/techstay/myscripts// @version 0.1// @description 將簡書文章復制到csdn和思否編輯器中// @author techstay// @match https://editor.csdn.net/md/// @match https://segmentfault.com/write// @match https://www.jianshu.com/writer*// @require https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js// @require https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.min.js// @grant GM_setValue// @grant GM_getValue// @grant GM_deleteValue// @grant unsafeWindow// @grant GM_setClipboard// @grant window.close// @grant window.focus// @grant GM_openInTab// ==/UserScript==(function () { 'use strict'; const SF_URL = 'https://segmentfault.com/write' const CSDN_URL = 'https://editor.csdn.net/md/' const SF_TITLE = 'sf_title' const SF_CONTENT = 'sf_content' const CSDN_TITLE = 'csdn_title' const CSDN_CONTENT = 'csdn_content' function saveArticle() { GM_setValue(CSDN_TITLE, $('._24i7u').val()) GM_setValue(CSDN_CONTENT, $('#arthur-editor').val()) GM_setValue(SF_TITLE, $('._24i7u').val()) GM_setValue(SF_CONTENT, $('#arthur-editor').val()) } function copyToCsdn() { var title = GM_getValue(CSDN_TITLE, '') var content = GM_getValue(CSDN_CONTENT, '') if (title != '' && content != '') { $('.article-bar__title').delay(2000).queue(function () { $('.article-bar__title').val(title) $('.editor__inner').text(content) GM_deleteValue(CSDN_TITLE) GM_deleteValue(CSDN_CONTENT) $(this).dequeue() }) } } function copyToSegmentFault() { $(document).ready(function () { var title = GM_getValue(SF_TITLE, '') var content = GM_getValue(SF_CONTENT, '') if (title != '' && content != '') { $('#title').delay(2000).queue(function () {  $('#title').val(title)  GM_setClipboard(content, 'text')  GM_deleteValue(SF_TITLE)  GM_deleteValue(SF_CONTENT)  $(this).dequeue() }) } }) } function addCopyButton() { $('body').append('<div id="copyToCS">雙擊復制到CSDN和思否</div>') $('#copyToCS').css('width', '200px') $('#copyToCS').css('position', 'absolute') $('#copyToCS').css('top', '70px') $('#copyToCS').css('left', '350px') $('#copyToCS').css('background-color', '#28a745') $('#copyToCS').css('color', 'white') $('#copyToCS').css('font-size', 'large') $('#copyToCS').css('z-index', 100) $('#copyToCS').css('border-radius', '25px') $('#copyToCS').css('text-align', 'center') $('#copyToCS').dblclick(function () { saveArticle() GM_openInTab(SF_URL, true) GM_openInTab(CSDN_URL, true) }) $('#copyToCS').draggable() } $(document).ready(function () { if (window.location.href.startsWith('https://www.jianshu.com')) { addCopyButton() } else if (window.location.href.startsWith(SF_URL)) { copyToSegmentFault() } else if (window.location.href.startsWith(CSDN_URL)) { copyToCsdn() } })})()

其他注意事項 腳本編寫流程

踩了幾天坑,最后總結一下編寫油猴腳本的一點步驟。首先要思考腳本的實現方式,需要用到什么API和權限,然后填寫好腳本的注釋信息。

然后將功能封裝成函數的形式,最后在腳本末尾調用實現的函數。寫的差不多的時候復制到瀏覽器中嘗試運行。

遇到困難的時候,可能需要直接在F12開發者工具里進行調試。有些網頁不用jQuery,為了方便,我們需要自己將jQuery導入到頁面中,可以將下面的代碼復制到瀏覽器控制臺中。

var jq = document.createElement('script');jq.src = "https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js";document.getElementsByTagName('head')[0].appendChild(jq);

發布腳本 更新URL

腳本做完了,自然是要共享出來讓大家一起使用的。當然既然要發布,自然要支持更新方便日后維護。方法也很簡單,直接在上面的注釋部分添加 updateURL 即可,然后設置腳本訪問地址。例如我要將腳本發布到Github上,就添加下面的注釋。

// @updateURL https://raw.githubusercontent.com/techstay/myscripts/master/tampermonkey/remind_me_vagrant_update.js

上傳腳本

油猴腳本支持好幾個網站,其中目前最主流的是 GreasyFork ,登錄這個網站注冊一個賬號,然后進入用戶頁面選擇提交腳本,然后填寫腳本代碼和各項信息。

這樣腳本就提交上去了,其他人也可以搜索到并安裝腳本了!

總結

到此這篇關于油猴腳本編寫教程詳解的文章就介紹到這了,更多相關油猴腳本編寫教程內容請搜索武林網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲视频欧美视频| 国产精品久久久久久久久久新婚| 国产一区二区三区日韩欧美| 精品国偷自产在线| 亚洲电影免费在线观看| 国产美女91呻吟求| 国产精品自产拍在线观看中文| www.美女亚洲精品| 亚洲精品www久久久久久广东| 最近中文字幕mv在线一区二区三区四区| 国产精品大陆在线观看| 欧美日韩在线视频观看| 韩日精品中文字幕| 日日噜噜噜夜夜爽亚洲精品| 国产一区二区激情| 久久全国免费视频| 国产伊人精品在线| 欧美日韩国产综合新一区| 国产亚洲人成a一在线v站| 日韩精品中文在线观看| 国产精品福利在线观看网址| 中文字幕亚洲一区二区三区五十路| 日韩av网站大全| 91a在线视频| 日韩一区二区久久久| 有码中文亚洲精品| 国产精品v片在线观看不卡| 国产精品久久久久久五月尺| 色偷偷88888欧美精品久久久| xvideos成人免费中文版| 欧美视频在线观看 亚洲欧| 久久亚洲精品毛片| 亚洲人成电影网站色xx| 在线电影av不卡网址| 精品福利一区二区| 国产福利精品av综合导导航| 国模精品一区二区三区色天香| 国产精品久久久久久av下载红粉| 欧美激情视频在线观看| 91精品国产高清| 九九热r在线视频精品| 日本午夜在线亚洲.国产| 国产精品免费久久久久影院| 日韩精品视频在线免费观看| 欧美成人合集magnet| 久久99青青精品免费观看| 亚洲另类激情图| 最新69国产成人精品视频免费| 欧美重口另类videos人妖| 亚洲国产精品久久久久秋霞不卡| 深夜精品寂寞黄网站在线观看| 久久久精品免费| 欧美性猛交xxxx偷拍洗澡| 亚洲第一中文字幕| 精品一区精品二区| 精品久久久久久中文字幕大豆网| 亚洲第一男人天堂| 国产不卡一区二区在线播放| 欧美精品激情blacked18| 成人综合网网址| 欧美国产日韩在线| 欧美激情在线狂野欧美精品| 国产一区二区三区三区在线观看| 久久久久久久久久久av| 中日韩美女免费视频网站在线观看| 欧美一区二粉嫩精品国产一线天| 亚洲精品电影在线观看| 国产精自产拍久久久久久| 欧美综合在线第二页| 欧美性xxxx在线播放| 国产ts人妖一区二区三区| 91精品久久久久久| 国产精品爽爽ⅴa在线观看| 中文字幕日韩精品在线观看| 国产精品日韩一区| 国产成人精品久久二区二区| 久久久伊人日本| 久久久久久久97| 欧美制服第一页| 狠狠干狠狠久久| 欧美激情乱人伦| 色综合久久天天综线观看| 亚洲欧洲av一区二区| 成人激情电影一区二区| 国产精品久久久久久久久久小说| 亚洲精品小视频| 国产精品美女呻吟| 在线视频精品一| 亚洲qvod图片区电影| 91亚洲国产成人久久精品网站| 在线成人免费网站| 国产精品看片资源| 亚洲aa中文字幕| 中文字幕日韩高清| 日韩毛片在线看| 色噜噜狠狠色综合网图区| 亚洲成人网久久久| 精品网站999www| 亚洲网站在线观看| 亚洲第一区第二区| 国产成人一区二区三区| 亚洲无限乱码一二三四麻| 91爱视频在线| 在线观看国产欧美| 欧美午夜精品在线| 最新91在线视频| 久久免费少妇高潮久久精品99| 欧美精品在线看| 久久久久久久一区二区三区| 欧美亚洲伦理www| 91精品国产综合久久久久久蜜臀| 欧美国产日韩精品| 欧美做受高潮1| 91国产高清在线| 欧洲一区二区视频| 亚洲精品永久免费| 成人在线观看视频网站| 久久的精品视频| 一本久久综合亚洲鲁鲁| 亚洲色图25p| 欧美视频免费在线| 国产成人精品久久亚洲高清不卡| 久久久久久国产三级电影| 亚洲天堂一区二区三区| 日韩亚洲精品电影| 亚洲第一二三四五区| 98视频在线噜噜噜国产| 国产精品扒开腿做爽爽爽的视频| 国内精久久久久久久久久人| 在线日韩中文字幕| 久久天天躁狠狠躁夜夜爽蜜月| 国产精品久久久久久久久久免费| 日韩成人黄色av| 国产精品久久久久久久久借妻| 精品视频久久久久久| 亚洲欧美激情另类校园| 一区二区三区视频在线| 精品久久久久久亚洲精品| 最近免费中文字幕视频2019| 国产一区二区久久精品| 亚洲人a成www在线影院| 亚洲free性xxxx护士白浆| 在线中文字幕日韩| 国产不卡精品视男人的天堂| 亚洲欧洲成视频免费观看| 亚洲国产精品字幕| 不卡av电影在线观看| 国产精品三级久久久久久电影| 亚洲精品丝袜日韩| 中文字幕日韩有码| 7777精品久久久久久| 日韩电影中文 亚洲精品乱码| 亚洲性无码av在线| 亚洲天天在线日亚洲洲精| 九九久久精品一区| 日韩专区中文字幕| 国产日韩欧美成人| 国产日韩在线免费| 一区二区三区国产在线观看| 久久亚洲综合国产精品99麻豆精品福利| 精品国产福利视频| 国产日韩欧美在线看| 亚洲一区二区三区777| 国产成人综合亚洲|