用戶:屠麟傲血/JavaScript手冊
| “ | 你學的是個錘子JavaScript,你學的是jQuery | ” |
| ——一名不願透露姓名的維護組成員 | ||
學習JavaScript不久,主要精力放在了jQuery上,把自己的一些心得記下來吧,或許有些naive。
常用mediaWiki函數
原文來自:mw:ResourceLoader/Core modules,但並不是直接翻譯,有一定的歸納總結。
mediaWiki提供了豐富的函數供使用,以下舉出一些常用的函數。在較新版本的mediaWiki上,它們大部分來自於mediawiki.base模塊,在mediaWiki上運行的js不需要調取該庫即可使用這些函數。對象的完整路徑是window.mediaWiki,常用的簡寫是mw。
mw.config
mediaWiki.config通過調用內部函數mw.Map來查詢各類元數據。常用的有如下幾種:
mw.config.get('参数名'),獲取參數用於後續代碼中;mw.config.exists('参数名')判斷這個參數是否存在;mw.config.set('参数名')能夠設置一個參數的值;
此外,mw.config.log('參數名')可以將獲得的參數直接寫入瀏覽器控制台,在「審查元素」中查看。config可以查詢的參數有很多,F12打開控制台,使用mw.config.values查詢即可獲得當前頁面的相關信息。
mw.html
mw.html.escape函數提供字符轉義功能。mw.html.element函數能夠在安全轉義的前提下,創建一個html元素。格式為mw.html.element('元素名',{属性},内容)。mw.html.Raw函數適用於mw.html.element編寫多層元素,為了讓子元素符號不被轉義,需要使用new mw.html.Raw()包裹子元素。
還是jQuery建html元素方便直接用Vanilla JS得了
mw.loader
這裏的一些函數不在mediawiki.base,不過在User和MediaWiki命名空間直接調用是沒問題的。
mw.loader.addStyleTag:生成一個<style>元素,寫入網頁窗口的<head>中。mw.loader.getScript:1.33+啟用,和jQuery.getScript具有相同的效果。但和jQuery.getScript相比默認開啟緩存,後續執行的函數用then方法調用。mw.loader.getState:判斷一個模塊的狀態,例如萌娘百科後台沒有es6-polyfills,返回null。mw.loader.load:加載其他代碼庫、js或css,格式如下:mw.loader.load('模块名'),多個模塊使用mw.loader.load(['模块1','模块2'])- 加載js:
mw.loader.load('//zh.moegirl.org.cn/w/index.php?title=MediaWiki:Gadget-HotCat.js&action=raw', 'text/javascript') - 加載css:
mw.loader.load('//zh.moegirl.org.cn/w/index.php?title=User:星海子/vector.css&action=raw', 'text/css')
mw.loader.state:更改一個模塊的狀態。mw.loader.using:基於jQuery的延遲對象加載其他代碼庫,然後調用庫內函數,格式為:mw.loader.using(["模块1","模块2",……,"模块n"],需要使用模块的函数,报错函数)。亦可用then(需要使用模塊的函數,報錯函數)、done/fail等方法來調用需要使用模塊的函數,表明實際的異步操作。
mw.now
mw.now等同於JavaScript中Date對象的getTime()函數,可以用其直接返回1970年1月1日0時0分0秒(UTC)至今的毫秒數。
mw.notify
mw.notify函數是mediawiki.notification.notify的簡寫,模塊名mediawiki.notify在舊版本mw中作為調用它的重新導向存在,該重新導向自1.35合併入mediawiki.base模塊中。該函數可以在網頁右上角顯示一個通知,如同氣泡一般,格式為mw.notify("消息内容",{通知属性})。通知屬性可以用的參數如下:
- autoHide和autoHideSeconds:設置通知顯示一段時間後隱藏。
- tag:同一時刻同樣tag的通知只會顯示一個,如果要顯示多個通知,就需要給通知設置不同的tag。
- title:設置通知的標題。
- type:快速設置通知的樣式,例如'warn'、'error'和'success'。
- id和classes:通過制定通知的id和classes來設置通知樣式。
mw.lib
想創建全局變量,又怕命名衝突?可以把變量塞進mw.lib里。
jQuery衍生庫
mediaWiki內置了豐富的jQuery衍生代碼庫。
chosen
chosen是一個jQuery第三方庫,可以用它快速生成一個下拉選擇菜單,mediaWiki的編輯標籤功能使用了這個庫。
client
client能夠獲取客戶端瀏覽器名稱、佈局、版本和作業系統信息,用於代替jQuery1.9版本中被廢棄的默認函數browser,共有2個用法:
$.client.profile:直接獲取客戶端瀏覽器和作業系統的信息,用於後續的判斷中。$.client.test:給出對瀏覽器和作業系統的限制信息,判斷當前客戶端是否符合要求,格式為$.client.test(限制,{配置},exactMatchOnly),配置不設置時調用$.client.profile,exactMatchOnly指是否在瀏覽器未找到時返回真值。
colorUtil
colorUtil提供了調色盤(colors)、亮度調整(getColorBrightness(currentColor, mod))、從CSS中尋找顏色(getRGB)、hsl模式與Rgb模式互轉(rgbToHsl、hslToRgb)功能。
jQuery UI
從1.29開始,mediaWiki不推薦使用jQuery UI,建議使用OOjs UI代替,除非:
- 用jQuery UI寫的東西配合
2010版wikieditor、gadget2.0、餵雞友愛、old vector使用,因為這個版本的編輯器使用jQuery UI; - OOjs-ui不能提供的功能,jQuery UI能夠提供。
1.34+的mw上提供完整的jQuery UI庫,但1.31版本mw的萌娘百科後台只有一個個小模塊。你需要這麼來調用:
- 根據你需要使用的模塊調用
jquery.ui.*(*為模塊名,如dialog, widget); 直接使用小工具提供的完整jquery.ui庫(因伺服器原因停止使用ext.gadget.jquery.ui)。
OOjs
面向對象(英語:Object-oriented),簡寫為OO,是當前MediaWiki推薦使用的JavaScript庫,可視化編輯器、交互式瀏覽歷史等使用它的UI庫作為界面UI。
常用後台模塊
mediawiki.api
mediaWiki提供的API模塊能夠給js提供數據庫讀寫功能,對jQuery.ajax的再次包裝使得它更加簡單易學。mediawiki還提供了ForeignApi功能,可以用它來在萌娘百科的頁面調取萌娘共享的api。
mediawiki.uri
uri用於設置一個外部連結,下面以一連結說明uri的基本參數:
http://username:[email protected]:81/dir/dir.2/index.html?q1=0&&test1&test2=&test3=value+%28escaped%29&r=1&r=2#top
該連結中包含了url的八個參數:協議(http)、用戶名(username)、密碼(password)、端口(81)、主機(www.example.com)、網頁路徑(dir/dir.2/index.html)、查詢目標(q1=0&&test1&test2=&test3=value+%28escaped%29&r=1&r=2)和章節(top),它們可以直接被讀寫。
可以使用new mw.Uri來定義一個新的uri,其擁有的方法列出部分如下:
- clone:克隆目標Uri,更加清晰地表現Uri的繼承關係;
- extend:以對象的形式向目標Uri添加查詢目標;
- toString:將Uri轉化為連結字符串輸出。
mediawiki.util
mw.util.addCSS在mw.loader.addStyleTag的基礎上,將這個樣式表定義為變量,通過sheet.disabled = !sheet.disabled這樣的語句使用按鈕對樣式進行開關。mw.util.addPortletLink可以在側邊欄,工具箱等處插入一個連結。語法是addPortletLink( portletId, 链接, 链接内容, 链接id, 链接标题, 键盘快捷键, 链接位置)。- 函數變量順序是固定的,空缺的值應當為null。
- 同默認的那些快捷鍵一樣,鍵盤快捷鍵使用時需要同時按下alt和shift。
- 插入的連結位置在指定位置之前。如果不指定連結位置或該位置不存在,則連結將以append的形式插入。
mw.util.getParamValue用於讀取連結中變量的值,格式為mw.util.getParamValue(变量名,链接)mw.util.isIPAddress可以判斷輸入的值是否為一個IP位址。同樣的,還有isIPv4Address和isIPv6Address判斷輸入的值是否為IPv4/IPv6地址。mw.util.wikiUrlencode按照PHP規範對連結的字符串進行編碼。
mediawiki.storage
mediawiki提供了safe storage類來包裝localstorage,不過在1.31不提供儲存json時與儲存時格式——字符串互相轉換的功能,也並不提供限時儲存數據的功能,這樣只要添加一個數據儲存時間(單位:s),不需要額外判斷時間就能從localstorage移除內容。
所以,這兩周還是用User:AnnAngela/js/LocalObjectStorage吧。
Moment
(待補充)
es6-polyfills
在1.36整合的es6-polyfills,提供了Array.prototype.find, Array.prototype.findIndex, Array.prototype.find, Array.prototype.includes和Promise的polyfill,在1.31的萌娘百科可以使用來自阿里雲、更全面的MediaWiki:Gadget-libPolyfill.js代替。
Vue
什麼嘛,這都2026年了,mediawiki還不支持符合程式設計師對未來js庫幻想的……哦是萌娘百科沒有升級到1.35啊,那……還是有事的,這兩年升到1.38才有前台能用的vue3。
下面將一個來自vue官網的例子本地化:
(async () => {
await Promise.all([$.ready, mw.loader.using(["vue"])]);
const { defineComponent, createApp } = Vue;
$("body").append('<div id="app"></div>');
const app = defineComponent({
template: `<div id="app">
<button @click="count++">{{ count }}</button>
</div>`,
data() {
return {
count: 0,
};
},
});
createApp(app).mount("#app");
})();
Widget調用js庫
從mediawiki1.32開始,ResourceLoader.php中Widget常用的RLQ接口新增了一個方法,來調用需要在代碼執行前加載的js庫:
/**
* Wrap JavaScript code to run after a required module.
*
* @since 1.32
* @param string|string[] $modules Module name(s)
* @param string $script JavaScript code
* @return string JavaScript code
*/
public static function makeInlineCodeWithModule( $modules, $script ) {
// Adds an array to lazy-created RLQ
return '(RLQ=window.RLQ||[]).push(['
. self::encodeJsonForScript( $modules ) . ','
. 'function(){' . trim( $script ) . '}'
. ']);';
}
對應的Widget代碼可以是:
window.RLQ = window.RLQ || [];
window.RLQ.push([module||["module1","module2",……"moduleN"],function(){
……
}]);
從1.34+開始,因為jQuery加載順序原因,一部分Widget需要這種方法進行調用jQuery(雖然jQuery默認加載),使用mw.loader.using調用的不少模塊也可以寫入此處。