在第一篇文章中唤蔗,我對用戶腳本進行了一些介紹,讓大家對其有個大概的了解窟赏。在這篇文章中措译,我會對用戶腳本開發(fā)過程中要用到的基礎(chǔ)知識做一些介紹,讓大家知道腳本中哪部分代碼是干什么的饰序,常用的操作有哪些。主要包括 3 個部分的介紹: 腳本頭部 UserScript
包含的腳本屬性规哪、腳本管理器提供的 API 以及腳本內(nèi)容中常用的 JS DOM 操作求豫。在后面的所有介紹中,我將使用 Chrome 瀏覽器和 Tampermonkey 腳本管理器來操作。
UserScript
打開任何一個腳本的源碼蝠嘉,都可以看到前面有這樣一段類似的代碼:
那么這段代碼是干什么用的呢最疆?是必須有還是可有可無呢?如果是必須有蚤告,那么新建一個腳本的時候應該怎么寫努酸,寫哪些?OK杜恰,我們來一一解釋获诈。
首先,這段代碼是用來給腳本設(shè)置屬性的心褐。比如說腳本叫什么名字舔涎,腳本的版本號是多少,腳本的作者是誰逗爹,腳本支持在哪些網(wǎng)站上運行等等亡嫌。其次,這段代碼必須有掘而,只是某些屬性可以不寫挟冠。腳本屬性的語法如下:
// ==UserScript==
// @key value
// ==/UserScript==
每一行都應該以 //
開頭,所有的屬性都應該被 ==UserScript==
和 ==/UserScript==
包含袍睡,一行只能寫一個屬性知染,前面寫屬性名,后面寫屬性值女蜈,中間用空格隔開持舆。下面讓我們來看看常用的屬性都有哪些,在什么情況下能用到哪個屬性伪窖。
@name
腳本的名稱逸寓,必填項。
@description
腳本的功能描述覆山,必填項竹伸。
@namespace
腳本的命名空間,一般如果自己有網(wǎng)站的話簇宽,可以寫自己網(wǎng)站的 URL勋篓。@namespace
和 @name
這兩個屬性被作為腳本的唯一標識符,腳本管理器根據(jù)它們來判斷一個腳本是否已安裝魏割。如果在更新腳本時更改了任意一項譬嚣,將發(fā)出警告,必填項钞它。
@version
腳本的版本號拜银,主要是為了更新腳本時使用殊鞭。每一次更新腳本都應該增加版本號,版本號可以寫成 0.1 或者 0.0.1 這樣尼桶,下次更新腳本的時候改為 0.2 或者 0.0.2 這樣操灿,必填項。
@author
腳本作者泵督,可選項趾盐。
@require
腳本需要的一些外部腳本文件,比如常用的有 jQuery 文件小腊,可選項救鲤。
@include
匹配腳本的運行網(wǎng)站,如果腳本要在多個網(wǎng)站上運行溢豆,需要寫多行蜒简,一行寫一個網(wǎng)站。跟 @match
二者必須有一項漩仙,否則腳本將不會再任何網(wǎng)站上運行搓茬。
@match
功能跟 @include
類似,在匹配網(wǎng)站時队他,如果不想寫的過于詳細卷仑,可以使用 *
來匹配任意字符,例如:
@match https://www.baidu.com/
這一句只有當網(wǎng)址完全匹配時腳本才能運行麸折,如果 URL 有任何多余字符腳本就不會運行锡凝。而下面這一句就可以匹配的更多:
@match *://*.baidu.com/*
這樣不管是以 http 開頭還是以 https 開頭,都能匹配垢啼,后面的網(wǎng)站不管是 www.baidu.com
還是 tieba.baidu.com
還是 www.baidu.com/s?wd=apple
之類的窜锯,都能匹配,腳本都會運行芭析。當然真正寫腳本的時候锚扎,就要注意觀察目標網(wǎng)站的 URL 規(guī)則,做到在需要運行腳本的網(wǎng)站上才讓腳本運行馁启。跟 @include
二者必須有一項驾孔,否則腳本將不會再任何網(wǎng)站上運行。
@exclude
排除腳本運行的網(wǎng)站惯疙,寫在這個屬性后面的網(wǎng)站翠勉,腳本將不會運行,可選項霉颠。
@resource
腳本用到的外部資源对碌,比如說腳本中要用到一些網(wǎng)絡圖片,就可以將圖片鏈接寫在這里蒿偎,并給圖片指定一個名稱朽们,這樣在腳本中就可以使用指定的名稱來拿到圖片了克伊。
@grant
指定腳本要用到的腳本管理器的 API,這些 API 能實現(xiàn)數(shù)據(jù)的存取华坦,將內(nèi)容復制到剪貼板,網(wǎng)絡請求不从,打開 tab 頁等功能惜姐,具體會在下一部分介紹。如果用不到就寫 none椿息,如果有多個歹袁,就寫多行,每行一個寝优。
上面介紹的是一些比較常用的屬性条舔,詳細屬性列表可以查看 Tampermonkey 文檔 或者 Greasemonkey 文檔。
腳本管理器的 API
為了讓開發(fā)腳本更方便乏矾,腳本管理器也為我們提供了很多 API孟抗,我們在腳本的開頭聲明后,就可以在代碼里面使用钻心。下面介紹一下常用的 API凄硼,有一點需要主要的是,Tampermonkey 和 Violentmonkey 提供的 API 是以 GM_*
的形式存在的捷沸,而 Greasemonkey 提供的 API 是以 GM.*
的形式存在的摊沉,同時有些 Tampermonkey 有的 API,在 Greasemonkey 里面并沒有 API 與之對應痒给。
GM_info
可以獲取一些腳本的信息,比如在屬性里面設(shè)置的腳本名稱,腳本作者网持,腳本描述荚恶,腳本版本號等等,但用的比較少序仙。示例:
GM_info.script.name
上述代碼可以用來在腳本中獲取腳本名稱突颊,值類型是 String。
GM_setValue(key,value)
用來存儲一些用戶設(shè)置的數(shù)據(jù)潘悼,如果腳本中有需要用戶進行個性化設(shè)置的內(nèi)容律秃,就可以使用這個函數(shù)進行存儲,比如文件的保存路徑之類的治唤。當下一次腳本更新時棒动,用戶之前設(shè)置的內(nèi)容依然保留,不會丟失宾添。示例:
GM_setValue("save_path"船惨,"D:\downloads\")
上述代碼設(shè)置了一條數(shù)據(jù)柜裸,即文件的保存路徑。鍵為 save_path
粱锐,值為 D:\downloads\
疙挺。key 的類型為 String,value 的類型可以是 String怜浅、Boolean铐然、Integer、Json 串恶座、List 等搀暑。有一點需要注意的是,在使用 Greasemonkey 的 GM.setValue(name,value)
時跨琳,value 的類型只能是 String自点、Boolean、Integer脉让。
GM_getValue(key,defaultValue)
用來獲取通過 GM_setValue(key,value)
設(shè)置的數(shù)據(jù)桂敛,可以設(shè)置默認值,這樣當取不到值時侠鳄,會使用默認值代替埠啃。示例:
String savePath = GM_getValue("save_path","E:\")
如果先使用 GM_setValue("save_path"伟恶,"D:\downloads\")
設(shè)置了值碴开,那么 savePath
的值將為 D:\downloads\
,否則 savePath
的值為 E:\
博秫。
GM_openInTab(url,loadInBackground)
用來在瀏覽器的新 tab 頁打開給定的 URL潦牛,url 是 String 類型,loadInBackground 可以是 Boolean 類型挡育,如果是 true巴碗,則當前 tab 不變,如果是 false即寒,則當前 tab 變?yōu)樾麓蜷_的 tab橡淆。示例:
GM_openInTab("https://www.baidu.com/",false)
上述代碼將會在新的 tab 頁打開百度,并將這個 tab 頁設(shè)置為當前 tab 頁母赵。
GM_getResourceURL(name)
用來獲取在腳本開頭通過 @resource
設(shè)置的外部資源的 URL逸爵,name 為 String 類型,示例:
// @resource up_button_icon https://coding.net/u/mofiter/p/public_files/git/raw/master/back_to_top_button.png
腳本開頭通過上述方式設(shè)置 icon 的名字為 up_button_icon
凹嘲,地址為 https://coding.net/u/mofiter/p/public_files/git/raw/master/back_to_top_button.png
师倔,在腳本中就可以通過下面的方式獲取到 icon 的 url:
img.src = GM_getResourceURL("up_button_icon")
GM_xmlhttpRequest(details)
用來進行網(wǎng)絡請求,有些腳本中可能需要對一些接口進行數(shù)據(jù)請求周蹭,就可以用到這個函數(shù)趋艘。details 是 json 類型疲恢,示例:
GM_xmlhttpRequest({
url:"http://127.0.0.1:6800/jsonrpc",
method:'POST',
data:JSON.stringify(json_rpc),
onerror:function(response){
console.log(response);
},
onload:function(response){
console.log(response);
}
});
其中,url 是要請求的接口地址瓷胧,method 是請求方法显拳,一般是 GET 或 POST,data 則是 POST 請求需要發(fā)送的數(shù)據(jù)搓萧,onerror 是錯誤回調(diào)函數(shù)萎攒,如果接口請求出錯,就會走這個回調(diào)矛绘,在函數(shù)里面進行錯誤處理,onload 是成功回調(diào)函數(shù)刃永,如果接口請求成功货矮,就會走這個回調(diào),在函數(shù)里面進行下一步操作斯够。當然還有很多參數(shù)可以設(shè)置囚玫,詳見 文檔。此段代碼詳見腳本 網(wǎng)易云課堂下載助手读规。
unsafeWindow
這個對象可以獲取到目標網(wǎng)站中的一些變量和 JavaScript 函數(shù)抓督。示例:
unsafeWindow.COVER_INFO
騰訊視頻電視劇的播放頁面有一個變量叫 COVER_INFO
,其中包含許多信息束亏,如果有需要铃在,可以通過這種方式取信息做一些操作。
上面介紹的是一些比較常用的 API碍遍,詳細 API 函數(shù)可以查看 Tampermonkey 文檔 或者 Greasemonkey 文檔定铜。
常用的 JS DOM 操作
腳本的目的是提供方便,給目標網(wǎng)站添加一些官方?jīng)]有提供的功能怕敬。要對原網(wǎng)站進行操作揣炕,可以使用 HTML,比較直觀东跪,但比較繁瑣畸陡,也可以使用 jQuery,比較簡潔虽填,但可能可讀性稍弱一點丁恭。如果要在腳本中使用 jQuery,需要先在腳本開頭使用 @resource
引入 jQuery 庫卤唉,具體引入哪一個版本涩惑,可以自己選擇。
// @require https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js
然后在代碼開頭定義變量 $
桑驱,這樣在后面就可以使用 $(selector).action()
選擇 HTML 元素并進行操作了竭恬。
var $ = window.$;
添加元素和刪除元素
最常見的需求是在目標網(wǎng)站添加一些元素或者刪除一些元素跛蛋。如果要刪除元素,那么我們需要先選擇我們要刪除的元素痊硕。在 HTML 中赊级, 選擇元素的方法有 getElementById()
、getElementsByClassName()
岔绸、getElementsByName()
理逊、getElementsByTagName()
、querySelector()
盒揉、querySelectorAll()
等晋被;在 jQuery 中,選擇元素的方法為 $()
刚盈,其中括號里面的選擇器可以用 #id
羡洛,.class
,標簽名
等藕漱。選擇了元素之后欲侮,我們就要刪除它。在 HTML 中肋联,removeChild()
用來刪除當前元素的子元素威蕉;在 jQuery 中,remove()
用來刪除當前元素和它的子元素橄仍,empty()
用來刪除當前元素的子元素韧涨,hide()
用來隱藏當前元素(相應地,show
用來顯示當前元素)侮繁。如果我們要添加元素氓奈,就要先創(chuàng)建元素。在 HTML 中鼎天,createElement
用來創(chuàng)建元素舀奶,appendChild()
用來給當前元素添加子元素,insertBefore()
用來在當前子元素前面加入一個新的子元素斋射;在 jQuery 中育勺,append()
用來在當前元素的結(jié)尾添加子元素,prepend()
用來在當前元素的開頭添加子元素罗岖,after()
用來在當前元素后面添加同級元素涧至,before()
用來在當前元素前面添加同級元素。
事件操作
當我們給目標網(wǎng)站添加了元素之后桑包,我們通常希望可以處理一些用戶操作南蓬。比如當用戶點擊按鈕時,我們希望觸發(fā)一些操作;當用戶鼠標進入某個元素時赘方,我們希望觸發(fā)一些操作烧颖;當用戶鼠標移出某個元素時,我們希望觸發(fā)一些操作等等窄陡。在 HTML 中炕淮,可以使用 addEventListener(event,function)
函數(shù)向某個元素添加時間監(jiān)聽。其中 event
表示用戶操作跳夭,比如 click
涂圆、mouseenter
、mouseleave
等币叹;而 function
為事件觸發(fā)后要執(zhí)行的函數(shù)润歉。在 jQuery 中,可以對選擇的元素直接調(diào)用相應的方法進行相應的操作颈抚。示例:
$("#button").click(function(){
console.log("點擊了按鈕");
});
$("#button").mouseenter(function(){
console.log("鼠標移入了按鈕");
});
$("#button").mouseleave(function(){
console.log("鼠標移出了按鈕");
});
也可以使用 on(event,function)
方法實現(xiàn)跟上面相同的操作卡辰。示例:
$("#button").on("click",function(){
console.log("點擊了按鈕");
});
$("#button").on("mouseenter",function(){
console.log("鼠標移入了按鈕");
});
$("#button").on("mouseleave",function(){
console.log("鼠標移出了按鈕");
});
總結(jié)
本文對腳本開發(fā)中需要用到的基礎(chǔ)知識做了一些介紹,包括腳本的屬性設(shè)置邪意、腳本管理器提供的函數(shù)支持以及一些 HTML 的元素操作。如果還有疑問反砌,可以留言雾鬼,從下一篇文章開始,將結(jié)合已經(jīng)完成的腳本示例宴树,講解在真正開發(fā)一個腳本的時候策菜,要考慮哪些東西,怎么寫好一個腳本酒贬。