';
+ if (keywords.length <= 0) return;
+ let count = 0;
+ // perform local searching
+ dataObj.then(data => {
+ data.forEach(data => {
+ let isMatch = true;
+ let dataTitle = data.title ? data.title.trim().toLowerCase() : "";
+ let dataTags = data.tags;
+ let oneImage = data.oneImage ?? "";
+ const dataContent = data.content
+ ? data.content
+ .trim()
+ .replace(/<[^>]+>/g, "")
+ .toLowerCase()
+ : "";
+ const dataUrl = data.url.startsWith("/") ? data.url : GLOBAL_CONFIG.root + data.url;
+ let indexTitle = -1;
+ let indexContent = -1;
+ let firstOccur = -1;
+ // only match articles with not empty titles and contents
+ if (dataTitle !== "" || dataContent !== "") {
+ keywords.forEach((keyword, i) => {
+ indexTitle = dataTitle.indexOf(keyword);
+ indexContent = dataContent.indexOf(keyword);
+ if (indexTitle < 0 && indexContent < 0) {
+ isMatch = false;
+ } else {
+ if (indexContent < 0) {
+ indexContent = 0;
+ }
+ if (i === 0) {
+ firstOccur = indexContent;
+ }
+ }
+ });
+ } else {
+ isMatch = false;
+ }
+
+ // show search results
+ if (isMatch) {
+ if (firstOccur >= 0) {
+ // cut out 130 characters
+ // let start = firstOccur - 30 < 0 ? 0 : firstOccur - 30
+ // let end = firstOccur + 50 > dataContent.length ? dataContent.length : firstOccur + 50
+ let start = firstOccur - 30;
+ let end = firstOccur + 100;
+ let pre = "";
+ let post = "";
+
+ if (start < 0) {
+ start = 0;
+ }
+
+ if (start === 0) {
+ end = 100;
+ } else {
+ pre = "...";
+ }
+
+ if (end > dataContent.length) {
+ end = dataContent.length;
+ } else {
+ post = "...";
+ }
+
+ let matchContent = dataContent.substring(start, end);
+
+ // highlight all keywords
+ keywords.forEach(keyword => {
+ const regS = new RegExp(keyword, "gi");
+ matchContent = matchContent.replace(regS, '
';
+ if (oneImage) {
+ str += `
`;
+ } else {
+ str += '
';
+ }
+
+ str += "
";
+
+ if (oneImage) {
+ str +=
+ '
' +
+ dataTitle +
+ "";
+ } else {
+ str +=
+ '
' +
+ dataTitle +
+ "";
+ }
+
+ count += 1;
+
+ if (dataContent !== "") {
+ str +=
+ '
' +
+ pre +
+ matchContent +
+ post +
+ "
";
+ }
+ if (dataTags.length) {
+ str += '
";
+ }
+ }
+ str += "
";
+ }
+ });
+ if (count === 0) {
+ str +=
+ '
' +
+ GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) +
+ "
";
+ }
+ str += "
";
+ $resultContent.innerHTML = str;
+ if (keywords[0] !== "") $loadingStatus.innerHTML = "";
+ window.pjax && window.pjax.refresh($resultContent);
+ });
+ });
+ };
+
+ searchClickFn();
+ searchClickFnOnce();
+
+ // pjax
+ window.addEventListener("pjax:complete", () => {
+ !anzhiyu.isHidden($searchMask) && closeSearch();
+ searchClickFn();
+ });
+});
diff --git a/js/tw_cn.js b/js/tw_cn.js
new file mode 100644
index 0000000..86a0d7b
--- /dev/null
+++ b/js/tw_cn.js
@@ -0,0 +1,130 @@
+document.addEventListener('DOMContentLoaded', function () {
+ const { defaultEncoding, translateDelay, msgToTraditionalChinese, msgToSimplifiedChinese } = GLOBAL_CONFIG.translate
+ const snackbarData = GLOBAL_CONFIG.Snackbar
+ let currentEncoding = defaultEncoding
+ const targetEncodingCookie = 'translate-chn-cht'
+ let targetEncoding =
+ saveToLocal.get(targetEncodingCookie) === undefined
+ ? defaultEncoding
+ : Number(saveToLocal.get('translate-chn-cht'))
+ let translateButtonObject, translateRightMenuButtonObject;
+ const isSnackbar = snackbarData !== undefined
+
+ function setLang () {
+ document.documentElement.lang = targetEncoding === 1 ? 'zh-TW' : 'zh-CN'
+ }
+
+ function translateText (txt) {
+ if (txt === '' || txt == null) return ''
+ if (currentEncoding === 1 && targetEncoding === 2) return Simplized(txt)
+ else if (currentEncoding === 2 && targetEncoding === 1) {
+ return Traditionalized(txt)
+ } else return txt
+ }
+
+ function translateBody (fobj) {
+ let objs
+ if (typeof fobj === 'object') objs = fobj.childNodes
+ else objs = document.body.childNodes
+ for (let i = 0; i < objs.length; i++) {
+ const obj = objs.item(i)
+ if (
+ '||BR|HR|'.indexOf('|' + obj.tagName + '|') > 0 ||
+ obj === translateButtonObject
+ ) {
+ continue
+ }
+ if (obj.title !== '' && obj.title != null) {
+ obj.title = translateText(obj.title)
+ }
+ if (obj.alt !== '' && obj.alt != null) obj.alt = translateText(obj.alt)
+ if (obj.placeholder !== '' && obj.placeholder != null) { obj.placeholder = translateText(obj.placeholder) }
+ if (
+ obj.tagName === 'INPUT' &&
+ obj.value !== '' &&
+ obj.type !== 'text' &&
+ obj.type !== 'hidden'
+ ) {
+ obj.value = translateText(obj.value)
+ }
+ if (obj.nodeType === 3) obj.data = translateText(obj.data)
+ else translateBody(obj)
+ }
+ }
+ function translatePage () {
+ if (targetEncoding === 1) {
+ currentEncoding = 1
+ targetEncoding = 2
+ translateButtonObject.textContent = msgToTraditionalChinese
+ isSnackbar && anzhiyu.snackbarShow(snackbarData.cht_to_chs)
+ } else if (targetEncoding === 2) {
+ currentEncoding = 2
+ targetEncoding = 1
+ translateButtonObject.textContent = msgToSimplifiedChinese
+ isSnackbar && anzhiyu.snackbarShow(snackbarData.chs_to_cht)
+ }
+ saveToLocal.set(targetEncodingCookie, targetEncoding, 2)
+ setLang()
+ translateBody()
+ }
+
+ function JTPYStr () {
+ return '万与丑专业丛东丝丢两严丧个丬丰临为丽举么义乌乐乔习乡书买乱争于亏云亘亚产亩亲亵亸亿仅从仑仓仪们价众优伙会伛伞伟传伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬俣俦俨俩俪俭债倾偬偻偾偿傥傧储傩儿兑兖党兰关兴兹养兽冁内冈册写军农冢冯冲决况冻净凄凉凌减凑凛几凤凫凭凯击凼凿刍划刘则刚创删别刬刭刽刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勐勚匀匦匮区医华协单卖卢卤卧卫却卺厂厅历厉压厌厍厕厢厣厦厨厩厮县参叆叇双发变叙叠叶号叹叽吁后吓吕吗吣吨听启吴呒呓呕呖呗员呙呛呜咏咔咙咛咝咤咴咸哌响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唣唤唿啧啬啭啮啰啴啸喷喽喾嗫呵嗳嘘嘤嘱噜噼嚣嚯团园囱围囵国图圆圣圹场坂坏块坚坛坜坝坞坟坠垄垅垆垒垦垧垩垫垭垯垱垲垴埘埙埚埝埯堑堕塆墙壮声壳壶壸处备复够头夸夹夺奁奂奋奖奥妆妇妈妩妪妫姗姜娄娅娆娇娈娱娲娴婳婴婵婶媪嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尧尴尸尽层屃屉届属屡屦屿岁岂岖岗岘岙岚岛岭岳岽岿峃峄峡峣峤峥峦崂崃崄崭嵘嵚嵛嵝嵴巅巩巯币帅师帏帐帘帜带帧帮帱帻帼幂幞干并广庄庆庐庑库应庙庞废庼廪开异弃张弥弪弯弹强归当录彟彦彻径徕御忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恳恶恸恹恺恻恼恽悦悫悬悭悯惊惧惨惩惫惬惭惮惯愍愠愤愦愿慑慭憷懑懒懔戆戋戏戗战戬户扎扑扦执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捞损捡换捣据捻掳掴掷掸掺掼揸揽揿搀搁搂搅携摄摅摆摇摈摊撄撑撵撷撸撺擞攒敌敛数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权条来杨杩杰极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桊桠桡桢档桤桥桦桧桨桩梦梼梾检棂椁椟椠椤椭楼榄榇榈榉槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵氇气氢氩氲汇汉污汤汹沓沟没沣沤沥沦沧沨沩沪沵泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪漤潆潇潋潍潜潴澜濑濒灏灭灯灵灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煅煳熘爱爷牍牦牵牺犊犟状犷犸犹狈狍狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珉珏珐珑珰珲琎琏琐琼瑶瑷璇璎瓒瓮瓯电画畅畲畴疖疗疟疠疡疬疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫癯皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硷碍碛碜碱碹磙礼祎祢祯祷祸禀禄禅离秃秆种积称秽秾稆税稣稳穑穷窃窍窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筑筚筛筜筝筹签简箓箦箧箨箩箪箫篑篓篮篱簖籁籴类籼粜粝粤粪粮糁糇紧絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肷肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艹艺节芈芗芜芦苁苇苈苋苌苍苎苏苘苹茎茏茑茔茕茧荆荐荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莜莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒇蒉蒋蒌蓝蓟蓠蓣蓥蓦蔷蔹蔺蔼蕲蕴薮藁藓虏虑虚虫虬虮虽虾虿蚀蚁蚂蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襁襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯詟誉誊讠计订讣认讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郄郏郐郑郓郦郧郸酝酦酱酽酾酿释里鉅鉴銮錾钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铍铎铏铐铑铒铕铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗错锚锜锞锟锠锡锢锣锤锥锦锨锩锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镆镇镈镉镊镌镍镎镏镐镑镒镕镖镗镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陧陨险随隐隶隽难雏雠雳雾霁霉霭靓静靥鞑鞒鞯鞴韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓魇魉鱼鱽鱾鱿鲀鲁鲂鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹯鹰鹱鹲鹳鹴鹾麦麸黄黉黡黩黪黾龙历志制一台皋准复猛钟注范签'
+ }
+ function FTPYStr () {
+ return '萬與醜專業叢東絲丟兩嚴喪個爿豐臨為麗舉麼義烏樂喬習鄉書買亂爭於虧雲亙亞產畝親褻嚲億僅從侖倉儀們價眾優夥會傴傘偉傳傷倀倫傖偽佇體餘傭僉俠侶僥偵側僑儈儕儂俁儔儼倆儷儉債傾傯僂僨償儻儐儲儺兒兌兗黨蘭關興茲養獸囅內岡冊寫軍農塚馮衝決況凍淨淒涼淩減湊凜幾鳳鳧憑凱擊氹鑿芻劃劉則剛創刪別剗剄劊劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳猛勩勻匭匱區醫華協單賣盧鹵臥衛卻巹廠廳曆厲壓厭厙廁廂厴廈廚廄廝縣參靉靆雙發變敘疊葉號歎嘰籲後嚇呂嗎唚噸聽啟吳嘸囈嘔嚦唄員咼嗆嗚詠哢嚨嚀噝吒噅鹹呱響啞噠嘵嗶噦嘩噲嚌噥喲嘜嗊嘮啢嗩唕喚呼嘖嗇囀齧囉嘽嘯噴嘍嚳囁嗬噯噓嚶囑嚕劈囂謔團園囪圍圇國圖圓聖壙場阪壞塊堅壇壢壩塢墳墜壟壟壚壘墾坰堊墊埡墶壋塏堖塒塤堝墊垵塹墮壪牆壯聲殼壺壼處備複夠頭誇夾奪奩奐奮獎奧妝婦媽嫵嫗媯姍薑婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬡嬪嬙嬤孫學孿寧寶實寵審憲宮寬賓寢對尋導壽將爾塵堯尷屍盡層屭屜屆屬屢屨嶼歲豈嶇崗峴嶴嵐島嶺嶽崠巋嶨嶧峽嶢嶠崢巒嶗崍嶮嶄嶸嶔崳嶁脊巔鞏巰幣帥師幃帳簾幟帶幀幫幬幘幗冪襆幹並廣莊慶廬廡庫應廟龐廢廎廩開異棄張彌弳彎彈強歸當錄彠彥徹徑徠禦憶懺憂愾懷態慫憮慪悵愴憐總懟懌戀懇惡慟懨愷惻惱惲悅愨懸慳憫驚懼慘懲憊愜慚憚慣湣慍憤憒願懾憖怵懣懶懍戇戔戲戧戰戩戶紮撲扡執擴捫掃揚擾撫拋摶摳掄搶護報擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏撈損撿換搗據撚擄摑擲撣摻摜摣攬撳攙擱摟攪攜攝攄擺搖擯攤攖撐攆擷擼攛擻攢敵斂數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權條來楊榪傑極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒棬椏橈楨檔榿橋樺檜槳樁夢檮棶檢欞槨櫝槧欏橢樓欖櫬櫚櫸檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆毀轂畢斃氈毿氌氣氫氬氳彙漢汙湯洶遝溝沒灃漚瀝淪滄渢溈滬濔濘淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦濫瀠瀟瀲濰潛瀦瀾瀨瀕灝滅燈靈災燦煬爐燉煒熗點煉熾爍爛烴燭煙煩燒燁燴燙燼熱煥燜燾煆糊溜愛爺牘犛牽犧犢強狀獷獁猶狽麅獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽瑉玨琺瓏璫琿璡璉瑣瓊瑤璦璿瓔瓚甕甌電畫暢佘疇癤療瘧癘瘍鬁瘡瘋皰屙癰痙癢瘂癆瘓癇癡癉瘮瘞瘺癟癱癮癭癩癬癲臒皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確鹼礙磧磣堿镟滾禮禕禰禎禱禍稟祿禪離禿稈種積稱穢穠穭稅穌穩穡窮竊竅窯竄窩窺竇窶豎競篤筍筆筧箋籠籩築篳篩簹箏籌簽簡籙簀篋籜籮簞簫簣簍籃籬籪籟糴類秈糶糲粵糞糧糝餱緊縶糸糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺絏紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏絛繼綈績緒綾緓續綺緋綽緔緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶線緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨翹翽翬耮耬聳恥聶聾職聹聯聵聰肅腸膚膁腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏臢輿艤艦艙艫艱豔艸藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇檾蘋莖蘢蔦塋煢繭荊薦薘莢蕘蓽蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞蓧萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蕆蕢蔣蔞藍薊蘺蕷鎣驀薔蘞藺藹蘄蘊藪槁蘚虜慮虛蟲虯蟣雖蝦蠆蝕蟻螞蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁銜補襯袞襖嫋褘襪襲襏裝襠褌褳襝褲襇褸襤繈襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶讋譽謄訁計訂訃認譏訐訌討讓訕訖訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑說誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗諡謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郤郟鄶鄭鄆酈鄖鄲醞醱醬釅釃釀釋裏钜鑒鑾鏨釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鈍鈔鍾鈉鋇鋼鈑鈐鑰欽鈞鎢鉤鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鈰鉉鉈鉍鈹鐸鉶銬銠鉺銪鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺錯錨錡錁錕錩錫錮鑼錘錐錦鍁錈錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鏌鎮鎛鎘鑷鐫鎳鎿鎦鎬鎊鎰鎔鏢鏜鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔鑣鑞鑲長門閂閃閆閈閉問闖閏闈閑閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隉隕險隨隱隸雋難雛讎靂霧霽黴靄靚靜靨韃鞽韉韝韋韌韍韓韙韞韜韻頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飆飛饗饜飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢魘魎魚魛魢魷魨魯魴魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鯵鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鱉鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鴬鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鶤鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺鸇鷹鸌鸏鸛鸘鹺麥麩黃黌黶黷黲黽龍歷誌製壹臺臯準復勐鐘註範籤'
+ }
+ function Traditionalized (cc) {
+ let str = ''
+ const ss = JTPYStr()
+ const tt = FTPYStr()
+ for (let i = 0; i < cc.length; i++) {
+ if (cc.charCodeAt(i) > 10000 && ss.indexOf(cc.charAt(i)) !== -1) {
+ str += tt.charAt(ss.indexOf(cc.charAt(i)))
+ } else str += cc.charAt(i)
+ }
+ return str
+ }
+ function Simplized (cc) {
+ let str = ''
+ const ss = JTPYStr()
+ const tt = FTPYStr()
+ for (let i = 0; i < cc.length; i++) {
+ if (cc.charCodeAt(i) > 10000 && tt.indexOf(cc.charAt(i)) !== -1) {
+ str += ss.charAt(tt.indexOf(cc.charAt(i)))
+ } else str += cc.charAt(i)
+ }
+ return str
+ }
+
+ function translateInitialization() {
+ translateButtonObject = document.getElementById('translateLink');
+ translateRightMenuButtonObject = document.getElementById('menu-translate').querySelector('span');
+
+ if (translateButtonObject || translateRightMenuButtonObject) {
+ if (currentEncoding !== targetEncoding) {
+ const textContent = targetEncoding === 1 ? msgToSimplifiedChinese : msgToTraditionalChinese;
+
+ if (translateButtonObject) {
+ translateButtonObject.textContent = textContent;
+ }
+
+ if (translateRightMenuButtonObject) {
+ translateRightMenuButtonObject.textContent = textContent;
+ }
+
+ setLang();
+ setTimeout(translateBody, translateDelay);
+ }
+ }
+ }
+
+ window.translateFn = {
+ translatePage,
+ Traditionalized,
+ Simplized
+ }
+
+ translateInitialization()
+ document.addEventListener('pjax:complete', translateInitialization)
+})
\ No newline at end of file
diff --git a/js/utils.js b/js/utils.js
new file mode 100644
index 0000000..01e887b
--- /dev/null
+++ b/js/utils.js
@@ -0,0 +1,1435 @@
+const anzhiyu = {
+ debounce: (func, wait = 0, immediate = false) => {
+ let timeout;
+ return (...args) => {
+ const later = () => {
+ timeout = null;
+ if (!immediate) func(...args);
+ };
+ const callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) func(...args);
+ };
+ },
+
+ throttle: function (func, wait, options = {}) {
+ let timeout, context, args;
+ let previous = 0;
+
+ const later = () => {
+ previous = options.leading === false ? 0 : new Date().getTime();
+ timeout = null;
+ func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+
+ const throttled = (...params) => {
+ const now = new Date().getTime();
+ if (!previous && options.leading === false) previous = now;
+ const remaining = wait - (now - previous);
+ context = this;
+ args = params;
+ if (remaining <= 0 || remaining > wait) {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ previous = now;
+ func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ };
+
+ return throttled;
+ },
+
+ sidebarPaddingR: () => {
+ const innerWidth = window.innerWidth;
+ const clientWidth = document.body.clientWidth;
+ const paddingRight = innerWidth - clientWidth;
+ if (innerWidth !== clientWidth) {
+ document.body.style.paddingRight = paddingRight + "px";
+ }
+ },
+
+ snackbarShow: (text, showActionFunction = false, duration = 2000, actionText = false) => {
+ const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar;
+ const bg = document.documentElement.getAttribute("data-theme") === "light" ? bgLight : bgDark;
+ const root = document.querySelector(":root");
+ root.style.setProperty("--anzhiyu-snackbar-time", duration + "ms");
+
+ Snackbar.show({
+ text: text,
+ backgroundColor: bg,
+ onActionClick: showActionFunction,
+ actionText: actionText,
+ showAction: actionText,
+ duration: duration,
+ pos: position,
+ customClass: "snackbar-css",
+ });
+ },
+
+ loadComment: (dom, callback) => {
+ if ("IntersectionObserver" in window) {
+ const observerItem = new IntersectionObserver(
+ entries => {
+ if (entries[0].isIntersecting) {
+ callback();
+ observerItem.disconnect();
+ }
+ },
+ { threshold: [0] }
+ );
+ observerItem.observe(dom);
+ } else {
+ callback();
+ }
+ },
+
+ scrollToDest: (pos, time = 500) => {
+ const currentPos = window.pageYOffset;
+ if ("scrollBehavior" in document.documentElement.style) {
+ window.scrollTo({
+ top: pos,
+ behavior: "smooth",
+ });
+ return;
+ }
+
+ let start = null;
+ pos = +pos;
+ window.requestAnimationFrame(function step(currentTime) {
+ start = !start ? currentTime : start;
+ const progress = currentTime - start;
+ if (currentPos < pos) {
+ window.scrollTo(0, ((pos - currentPos) * progress) / time + currentPos);
+ } else {
+ window.scrollTo(0, currentPos - ((currentPos - pos) * progress) / time);
+ }
+ if (progress < time) {
+ window.requestAnimationFrame(step);
+ } else {
+ window.scrollTo(0, pos);
+ }
+ });
+ },
+
+ initJustifiedGallery: function (selector) {
+ const runJustifiedGallery = i => {
+ if (!anzhiyu.isHidden(i)) {
+ fjGallery(i, {
+ itemSelector: ".fj-gallery-item",
+ rowHeight: i.getAttribute("data-rowHeight"),
+ gutter: 4,
+ onJustify: function () {
+ this.$container.style.opacity = "1";
+ },
+ });
+ }
+ };
+
+ if (Array.from(selector).length === 0) runJustifiedGallery(selector);
+ else
+ selector.forEach(i => {
+ runJustifiedGallery(i);
+ });
+ },
+
+ animateIn: (ele, text) => {
+ ele.style.display = "block";
+ ele.style.animation = text;
+ },
+
+ animateOut: (ele, text) => {
+ ele.addEventListener("animationend", function f() {
+ ele.style.display = "";
+ ele.style.animation = "";
+ ele.removeEventListener("animationend", f);
+ });
+ ele.style.animation = text;
+ },
+
+ /**
+ * @param {*} selector
+ * @param {*} eleType the type of create element
+ * @param {*} options object key: value
+ */
+ wrap: (selector, eleType, options) => {
+ const creatEle = document.createElement(eleType);
+ for (const [key, value] of Object.entries(options)) {
+ creatEle.setAttribute(key, value);
+ }
+ selector.parentNode.insertBefore(creatEle, selector);
+ creatEle.appendChild(selector);
+ },
+
+ isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
+
+ getEleTop: ele => {
+ let actualTop = ele.offsetTop;
+ let current = ele.offsetParent;
+
+ while (current !== null) {
+ actualTop += current.offsetTop;
+ current = current.offsetParent;
+ }
+
+ return actualTop;
+ },
+
+ loadLightbox: ele => {
+ const service = GLOBAL_CONFIG.lightbox;
+
+ if (service === "mediumZoom") {
+ const zoom = mediumZoom(ele);
+ zoom.on("open", e => {
+ const photoBg = document.documentElement.getAttribute("data-theme") === "dark" ? "#121212" : "#fff";
+ zoom.update({
+ background: photoBg,
+ });
+ });
+ }
+
+ if (service === "fancybox") {
+ Array.from(ele).forEach(i => {
+ if (i.parentNode.tagName !== "A") {
+ const dataSrc = i.dataset.lazySrc || i.src;
+ const dataCaption = i.title || i.alt || "";
+ anzhiyu.wrap(i, "a", {
+ href: dataSrc,
+ "data-fancybox": "gallery",
+ "data-caption": dataCaption,
+ "data-thumb": dataSrc,
+ });
+ }
+ });
+
+ if (!window.fancyboxRun) {
+ Fancybox.bind("[data-fancybox]", {
+ Hash: false,
+ Thumbs: {
+ autoStart: false,
+ },
+ });
+ window.fancyboxRun = true;
+ }
+ }
+ },
+
+ setLoading: {
+ add: ele => {
+ const html = `
+
+ `;
+ ele.insertAdjacentHTML("afterend", html);
+ },
+ remove: ele => {
+ ele.nextElementSibling.remove();
+ },
+ },
+
+ updateAnchor: anchor => {
+ if (anchor !== window.location.hash) {
+ if (!anchor) anchor = location.pathname;
+ const title = GLOBAL_CONFIG_SITE.title;
+ window.history.replaceState(
+ {
+ url: location.href,
+ title,
+ },
+ title,
+ anchor
+ );
+ }
+ },
+
+ getScrollPercent: (currentTop, ele) => {
+ const docHeight = ele.clientHeight;
+ const winHeight = document.documentElement.clientHeight;
+ const headerHeight = ele.offsetTop;
+ const contentMath =
+ docHeight > winHeight ? docHeight - winHeight : document.documentElement.scrollHeight - winHeight;
+ const scrollPercent = (currentTop - headerHeight) / contentMath;
+ const scrollPercentRounded = Math.round(scrollPercent * 100);
+ const percentage = scrollPercentRounded > 100 ? 100 : scrollPercentRounded <= 0 ? 0 : scrollPercentRounded;
+ return percentage;
+ },
+
+ addGlobalFn: (key, fn, name = false, parent = window) => {
+ const globalFn = parent.globalFn || {};
+ const keyObj = globalFn[key] || {};
+
+ if (name && keyObj[name]) return;
+
+ name = name || Object.keys(keyObj).length;
+ keyObj[name] = fn;
+ globalFn[key] = keyObj;
+ parent.globalFn = globalFn;
+ },
+
+ addEventListenerPjax: (ele, event, fn, option = false) => {
+ ele.addEventListener(event, fn, option);
+ anzhiyu.addGlobalFn("pjax", () => {
+ ele.removeEventListener(event, fn, option);
+ });
+ },
+
+ removeGlobalFnEvent: (key, parent = window) => {
+ const { globalFn = {} } = parent;
+ const keyObj = globalFn[key] || {};
+ const keyArr = Object.keys(keyObj);
+ if (!keyArr.length) return;
+ keyArr.forEach(i => {
+ keyObj[i]();
+ });
+ delete parent.globalFn[key];
+ },
+
+ //更改主题色
+ changeThemeMetaColor: function (color) {
+ // console.info(`%c ${color}`, `font-size:36px;color:${color};`);
+ if (themeColorMeta !== null) {
+ themeColorMeta.setAttribute("content", color);
+ }
+ },
+
+ //顶栏自适应主题色
+ initThemeColor: function () {
+ let themeColor = getComputedStyle(document.documentElement)
+ .getPropertyValue("--anzhiyu-bar-background")
+ .trim()
+ .replace('"', "")
+ .replace('"', "");
+ const currentTop = window.scrollY || document.documentElement.scrollTop;
+ if (currentTop > 26) {
+ if (anzhiyu.is_Post()) {
+ themeColor = getComputedStyle(document.documentElement)
+ .getPropertyValue("--anzhiyu-meta-theme-post-color")
+ .trim()
+ .replace('"', "")
+ .replace('"', "");
+ }
+ if (themeColorMeta.getAttribute("content") === themeColor) return;
+ this.changeThemeMetaColor(themeColor);
+ } else {
+ if (themeColorMeta.getAttribute("content") === themeColor) return;
+ this.changeThemeMetaColor(themeColor);
+ }
+ },
+ //是否是文章页
+ is_Post: function () {
+ var url = window.location.href; //获取url
+ if (url.indexOf("/posts/") >= 0) {
+ //判断url地址中是否包含code字符串
+ return true;
+ } else {
+ return false;
+ }
+ },
+ //监测是否在页面开头
+ addNavBackgroundInit: function () {
+ var scrollTop = 0,
+ bodyScrollTop = 0,
+ documentScrollTop = 0;
+ if ($bodyWrap) {
+ bodyScrollTop = $bodyWrap.scrollTop;
+ }
+ if (document.documentElement) {
+ documentScrollTop = document.documentElement.scrollTop;
+ }
+ scrollTop = bodyScrollTop - documentScrollTop > 0 ? bodyScrollTop : documentScrollTop;
+
+ if (scrollTop != 0) {
+ pageHeaderEl.classList.add("nav-fixed");
+ pageHeaderEl.classList.add("nav-visible");
+ }
+ },
+ // 下载图片
+ downloadImage: function (imgsrc, name) {
+ //下载图片地址和图片名
+ rm.hideRightMenu();
+ if (rm.downloadimging == false) {
+ rm.downloadimging = true;
+ anzhiyu.snackbarShow("正在下载中,请稍后", false, 10000);
+ setTimeout(function () {
+ let image = new Image();
+ // 解决跨域 Canvas 污染问题
+ image.setAttribute("crossOrigin", "anonymous");
+ image.onload = function () {
+ let canvas = document.createElement("canvas");
+ canvas.width = image.width;
+ canvas.height = image.height;
+ let context = canvas.getContext("2d");
+ context.drawImage(image, 0, 0, image.width, image.height);
+ let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
+ let a = document.createElement("a"); // 生成一个a元素
+ let event = new MouseEvent("click"); // 创建一个单击事件
+ a.download = name || "photo"; // 设置图片名称
+ a.href = url; // 将生成的URL设置为a.href属性
+ a.dispatchEvent(event); // 触发a的单击事件
+ };
+ image.src = imgsrc;
+ anzhiyu.snackbarShow("图片已添加盲水印,请遵守版权协议");
+ rm.downloadimging = false;
+ }, "10000");
+ } else {
+ anzhiyu.snackbarShow("有正在进行中的下载,请稍后再试");
+ }
+ },
+ //禁止图片右键单击
+ stopImgRightDrag: function () {
+ var img = document.getElementsByTagName("img");
+ for (var i = 0; i < img.length; i++) {
+ img[i].addEventListener("dragstart", function () {
+ return false;
+ });
+ }
+ },
+ //滚动到指定id
+ scrollTo: function (id) {
+ var domTop = document.querySelector(id).offsetTop;
+ window.scrollTo(0, domTop - 80);
+ },
+ //隐藏侧边栏
+ hideAsideBtn: () => {
+ // Hide aside
+ const $htmlDom = document.documentElement.classList;
+ $htmlDom.contains("hide-aside")
+ ? saveToLocal.set("aside-status", "show", 2)
+ : saveToLocal.set("aside-status", "hide", 2);
+ $htmlDom.toggle("hide-aside");
+ $htmlDom.contains("hide-aside")
+ ? document.querySelector("#consoleHideAside").classList.add("on")
+ : document.querySelector("#consoleHideAside").classList.remove("on");
+ },
+ // 热评切换
+ switchCommentBarrage: function () {
+ let commentBarrage = document.querySelector(".comment-barrage");
+ if (commentBarrage) {
+ if (window.getComputedStyle(commentBarrage).display === "flex") {
+ commentBarrage.style.display = "none";
+ anzhiyu.snackbarShow("✨ 已关闭评论弹幕");
+ document.querySelector(".menu-commentBarrage-text").textContent = "显示热评";
+ document.querySelector("#consoleCommentBarrage").classList.remove("on");
+ localStorage.setItem("commentBarrageSwitch", "false");
+ } else {
+ commentBarrage.style.display = "flex";
+ document.querySelector(".menu-commentBarrage-text").textContent = "关闭热评";
+ document.querySelector("#consoleCommentBarrage").classList.add("on");
+ anzhiyu.snackbarShow("✨ 已开启评论弹幕");
+ localStorage.removeItem("commentBarrageSwitch");
+ }
+ }
+ rm && rm.hideRightMenu();
+ },
+ initPaginationObserver: () => {
+ const commentElement = document.getElementById("post-comment");
+ const paginationElement = document.getElementById("pagination");
+
+ if (commentElement && paginationElement) {
+ new IntersectionObserver(entries => {
+ const commentBarrage = document.querySelector(".comment-barrage");
+
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ paginationElement.classList.add("show-window");
+ if (commentBarrage) {
+ commentBarrage.style.bottom = "-200px";
+ }
+ } else {
+ paginationElement.classList.remove("show-window");
+ if (commentBarrage) {
+ commentBarrage.style.bottom = "0px";
+ }
+ }
+ });
+ }).observe(commentElement);
+ }
+ },
+ // 初始化即刻
+ initIndexEssay: function () {
+ if (!document.getElementById("bbTimeList")) return;
+ setTimeout(() => {
+ let essay_bar_swiper = new Swiper(".essay_bar_swiper_container", {
+ passiveListeners: true,
+ direction: "vertical",
+ loop: true,
+ autoplay: {
+ disableOnInteraction: true,
+ delay: 3000,
+ },
+ mousewheel: true,
+ });
+
+ let essay_bar_comtainer = document.getElementById("bbtalk");
+ if (essay_bar_comtainer !== null) {
+ essay_bar_comtainer.onmouseenter = function () {
+ essay_bar_swiper.autoplay.stop();
+ };
+ essay_bar_comtainer.onmouseleave = function () {
+ essay_bar_swiper.autoplay.start();
+ };
+ }
+ }, 100);
+ },
+ scrollByMouseWheel: function ($list, $target) {
+ const scrollHandler = function (e) {
+ $list.scrollLeft -= e.wheelDelta / 2;
+ e.preventDefault();
+ };
+ $list.addEventListener("mousewheel", scrollHandler, { passive: false });
+ if ($target) {
+ $target.classList.add("selected");
+ $list.scrollLeft = $target.offsetLeft - $list.offsetLeft - ($list.offsetWidth - $target.offsetWidth) / 2;
+ }
+ },
+ // catalog激活
+ catalogActive: function () {
+ const $list = document.getElementById("catalog-list");
+ if ($list) {
+ const pathname = decodeURIComponent(window.location.pathname);
+ const catalogListItems = $list.querySelectorAll(".catalog-list-item");
+
+ let $catalog = null;
+ catalogListItems.forEach(item => {
+ if (pathname.startsWith(item.id)) {
+ $catalog = item;
+ return;
+ }
+ });
+
+ anzhiyu.scrollByMouseWheel($list, $catalog);
+ }
+ },
+ // Page Tag 激活
+ tagsPageActive: function () {
+ const $list = document.getElementById("tag-page-tags");
+ if ($list) {
+ const $tagPageTags = document.getElementById(decodeURIComponent(window.location.pathname));
+ anzhiyu.scrollByMouseWheel($list, $tagPageTags);
+ }
+ },
+ // 修改时间显示"最近"
+ diffDate: function (d, more = false, simple = false) {
+ const dateNow = new Date();
+ const datePost = new Date(d);
+ const dateDiff = dateNow.getTime() - datePost.getTime();
+ const minute = 1000 * 60;
+ const hour = minute * 60;
+ const day = hour * 24;
+ const month = day * 30;
+
+ let result;
+ if (more) {
+ const monthCount = dateDiff / month;
+ const dayCount = dateDiff / day;
+ const hourCount = dateDiff / hour;
+ const minuteCount = dateDiff / minute;
+
+ if (monthCount >= 1) {
+ result = datePost.toLocaleDateString().replace(/\//g, "-");
+ } else if (dayCount >= 1) {
+ result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day;
+ } else if (hourCount >= 1) {
+ result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour;
+ } else if (minuteCount >= 1) {
+ result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min;
+ } else {
+ result = GLOBAL_CONFIG.date_suffix.just;
+ }
+ } else if (simple) {
+ const monthCount = dateDiff / month;
+ const dayCount = dateDiff / day;
+ const hourCount = dateDiff / hour;
+ const minuteCount = dateDiff / minute;
+ if (monthCount >= 1) {
+ result = datePost.toLocaleDateString().replace(/\//g, "-");
+ } else if (dayCount >= 1 && dayCount <= 3) {
+ result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day;
+ } else if (dayCount > 3) {
+ result = datePost.getMonth() + 1 + "/" + datePost.getDate();
+ } else if (hourCount >= 1) {
+ result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour;
+ } else if (minuteCount >= 1) {
+ result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min;
+ } else {
+ result = GLOBAL_CONFIG.date_suffix.just;
+ }
+ } else {
+ result = parseInt(dateDiff / day);
+ }
+ return result;
+ },
+
+ // 修改即刻中的时间显示
+ changeTimeInEssay: function () {
+ document.querySelector("#bber") &&
+ document.querySelectorAll("#bber time").forEach(function (e) {
+ var t = e,
+ datetime = t.getAttribute("datetime");
+ (t.innerText = anzhiyu.diffDate(datetime, true)), (t.style.display = "inline");
+ });
+ },
+ // 修改相册集中的时间
+ changeTimeInAlbumDetail: function () {
+ document.querySelector("#album_detail") &&
+ document.querySelectorAll("#album_detail time").forEach(function (e) {
+ var t = e,
+ datetime = t.getAttribute("datetime");
+ (t.innerText = anzhiyu.diffDate(datetime, true)), (t.style.display = "inline");
+ });
+ },
+ // 刷新瀑布流
+ reflashEssayWaterFall: function () {
+ const waterfallEl = document.getElementById("waterfall");
+ if (waterfallEl) {
+ setTimeout(function () {
+ waterfall(waterfallEl);
+ waterfallEl.classList.add("show");
+ }, 800);
+ }
+ },
+ sayhi: function () {
+ const $sayhiEl = document.getElementById("author-info__sayhi");
+
+ const getTimeState = () => {
+ const hour = new Date().getHours();
+ let message = "";
+
+ if (hour >= 0 && hour <= 5) {
+ message = "睡个好觉,保证精力充沛";
+ } else if (hour > 5 && hour <= 10) {
+ message = "一日之计在于晨";
+ } else if (hour > 10 && hour <= 14) {
+ message = "吃饱了才有力气干活";
+ } else if (hour > 14 && hour <= 18) {
+ message = "集中精力,攻克难关";
+ } else if (hour > 18 && hour <= 24) {
+ message = "不要太劳累了,早睡更健康";
+ }
+
+ return message;
+ };
+
+ if ($sayhiEl) {
+ $sayhiEl.innerHTML = getTimeState();
+ }
+ },
+
+ // 友链注入预设评论
+ addFriendLink() {
+ var input = document.getElementsByClassName("el-textarea__inner")[0];
+ if (!input) return;
+ const evt = new Event("input", { cancelable: true, bubbles: true });
+ const defaultPlaceholder =
+ "昵称(请勿包含博客等字样):\n网站地址(要求博客地址,请勿提交个人主页):\n头像图片url(请提供尽可能清晰的图片,我会上传到我自己的图床):\n描述:\n站点截图(可选):\n";
+ input.value = this.getConfigIfPresent(GLOBAL_CONFIG.linkPageTop, "addFriendPlaceholder", defaultPlaceholder);
+ input.dispatchEvent(evt);
+ input.focus();
+ input.setSelectionRange(-1, -1);
+ },
+ // 获取配置,如果为空则返回默认值
+ getConfigIfPresent: function (config, configKey, defaultValue) {
+ if (!config) return defaultValue;
+ if (!config.hasOwnProperty(configKey)) return defaultValue;
+ if (!config[configKey]) return defaultValue;
+ return config[configKey];
+ },
+ //切换音乐播放状态
+ musicToggle: function (changePaly = true) {
+ if (!anzhiyu_musicFirst) {
+ anzhiyu.musicBindEvent();
+ anzhiyu_musicFirst = true;
+ }
+ let msgPlay = '
播放音乐';
+ let msgPause = '
暂停音乐';
+ if (anzhiyu_musicPlaying) {
+ navMusicEl.classList.remove("playing");
+ document.getElementById("menu-music-toggle").innerHTML = msgPlay;
+ document.getElementById("nav-music-hoverTips").innerHTML = "音乐已暂停";
+ document.querySelector("#consoleMusic").classList.remove("on");
+ anzhiyu_musicPlaying = false;
+ navMusicEl.classList.remove("stretch");
+ } else {
+ navMusicEl.classList.add("playing");
+ document.getElementById("menu-music-toggle").innerHTML = msgPause;
+ document.querySelector("#consoleMusic").classList.add("on");
+ anzhiyu_musicPlaying = true;
+ navMusicEl.classList.add("stretch");
+ }
+ if (changePaly) document.querySelector("#nav-music meting-js").aplayer.toggle();
+ rm && rm.hideRightMenu();
+ },
+ // 音乐伸缩
+ musicTelescopic: function () {
+ if (navMusicEl.classList.contains("stretch")) {
+ navMusicEl.classList.remove("stretch");
+ } else {
+ navMusicEl.classList.add("stretch");
+ }
+ },
+
+ //音乐上一曲
+ musicSkipBack: function () {
+ navMusicEl.querySelector("meting-js").aplayer.skipBack();
+ rm && rm.hideRightMenu();
+ },
+
+ //音乐下一曲
+ musicSkipForward: function () {
+ navMusicEl.querySelector("meting-js").aplayer.skipForward();
+ rm && rm.hideRightMenu();
+ },
+
+ //获取音乐中的名称
+ musicGetName: function () {
+ var x = document.querySelector(".aplayer-title");
+ var arr = [];
+ for (var i = x.length - 1; i >= 0; i--) {
+ arr[i] = x[i].innerText;
+ }
+ return arr[0];
+ },
+
+ //初始化console图标
+ initConsoleState: function () {
+ //初始化隐藏边栏
+ const $htmlDomClassList = document.documentElement.classList;
+ $htmlDomClassList.contains("hide-aside")
+ ? document.querySelector("#consoleHideAside").classList.add("on")
+ : document.querySelector("#consoleHideAside").classList.remove("on");
+ },
+
+ // 显示打赏中控台
+ rewardShowConsole: function () {
+ // 判断是否为赞赏打开控制台
+ consoleEl.classList.add("reward-show");
+ anzhiyu.initConsoleState();
+ },
+ // 显示中控台
+ showConsole: function () {
+ consoleEl.classList.add("show");
+ anzhiyu.initConsoleState();
+ },
+
+ //隐藏中控台
+ hideConsole: function () {
+ if (consoleEl.classList.contains("show")) {
+ // 如果是一般控制台,就关闭一般控制台
+ consoleEl.classList.remove("show");
+ } else if (consoleEl.classList.contains("reward-show")) {
+ // 如果是打赏控制台,就关闭打赏控制台
+ consoleEl.classList.remove("reward-show");
+ }
+ // 获取center-console元素
+ const centerConsole = document.getElementById("center-console");
+
+ // 检查center-console是否被选中
+ if (centerConsole.checked) {
+ // 取消选中状态
+ centerConsole.checked = false;
+ }
+ },
+ // 取消加载动画
+ hideLoading: function () {
+ document.getElementById("loading-box").classList.add("loaded");
+ },
+ // 将音乐缓存播放
+ cacheAndPlayMusic() {
+ let data = localStorage.getItem("musicData");
+ if (data) {
+ data = JSON.parse(data);
+ const currentTime = new Date().getTime();
+ if (currentTime - data.timestamp < 24 * 60 * 60 * 1000) {
+ // 如果缓存的数据没有过期,直接使用
+ anzhiyu.playMusic(data.songs);
+ return;
+ }
+ }
+
+ // 否则重新从服务器获取数据
+ fetch("/json/music.json")
+ .then(response => response.json())
+ .then(songs => {
+ const cacheData = {
+ timestamp: new Date().getTime(),
+ songs: songs,
+ };
+ localStorage.setItem("musicData", JSON.stringify(cacheData));
+ anzhiyu.playMusic(songs);
+ });
+ },
+ // 播放音乐
+ playMusic(songs) {
+ const anMusicPage = document.getElementById("anMusic-page");
+ const metingAplayer = anMusicPage.querySelector("meting-js").aplayer;
+ const randomIndex = Math.floor(Math.random() * songs.length);
+ const randomSong = songs[randomIndex];
+ const allAudios = metingAplayer.list.audios;
+ if (!selectRandomSong.includes(randomSong.name)) {
+ // 如果随机到的歌曲已经未被随机到过,就添加进metingAplayer.list
+ metingAplayer.list.add([randomSong]);
+ // 播放最后一首(因为是添加到了最后)
+ metingAplayer.list.switch(allAudios.length);
+ // 添加到已被随机的歌曲列表
+ selectRandomSong.push(randomSong.name);
+ } else {
+ // 随机到的歌曲已经在播放列表中了
+ // 直接继续随机直到随机到没有随机过的歌曲,如果全部随机过了就切换到对应的歌曲播放即可
+ let songFound = false;
+ while (!songFound) {
+ const newRandomIndex = Math.floor(Math.random() * songs.length);
+ const newRandomSong = songs[newRandomIndex];
+ if (!selectRandomSong.includes(newRandomSong.name)) {
+ metingAplayer.list.add([newRandomSong]);
+ metingAplayer.list.switch(allAudios.length);
+ selectRandomSong.push(newRandomSong.name);
+ songFound = true;
+ }
+ // 如果全部歌曲都已被随机过,跳出循环
+ if (selectRandomSong.length === songs.length) {
+ break;
+ }
+ }
+ if (!songFound) {
+ // 如果全部歌曲都已被随机过,切换到对应的歌曲播放
+ const palyMusicIndex = allAudios.findIndex(song => song.name === randomSong.name);
+ if (palyMusicIndex != -1) metingAplayer.list.switch(palyMusicIndex);
+ }
+ }
+
+ console.info("已随机歌曲:", selectRandomSong, "本次随机歌曲:", randomSong.name);
+ },
+ // 音乐节目切换背景
+ changeMusicBg: function (isChangeBg = true) {
+ const anMusicBg = document.getElementById("an_music_bg");
+
+ if (isChangeBg) {
+ // player listswitch 会进入此处
+ const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
+ anMusicBg.style.backgroundImage = musiccover.style.backgroundImage;
+ } else {
+ // 第一次进入,绑定事件,改背景
+ let timer = setInterval(() => {
+ const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
+ // 确保player加载完成
+ if (musiccover) {
+ clearInterval(timer);
+ // 绑定事件
+ anzhiyu.addEventListenerMusic();
+ // 确保第一次能够正确替换背景
+ anzhiyu.changeMusicBg();
+
+ // 暂停nav的音乐
+ if (
+ document.querySelector("#nav-music meting-js").aplayer &&
+ !document.querySelector("#nav-music meting-js").aplayer.audio.paused
+ ) {
+ anzhiyu.musicToggle();
+ }
+ }
+ }, 100);
+ }
+ },
+ // 获取自定义播放列表
+ getCustomPlayList: function () {
+ if (!window.location.pathname.startsWith("/music/")) {
+ return;
+ }
+ const urlParams = new URLSearchParams(window.location.search);
+ const userId = "8152976493";
+ const userServer = "netease";
+ const anMusicPageMeting = document.getElementById("anMusic-page-meting");
+ if (urlParams.get("id") && urlParams.get("server")) {
+ const id = urlParams.get("id");
+ const server = urlParams.get("server");
+ anMusicPageMeting.innerHTML = `
`;
+ } else {
+ anMusicPageMeting.innerHTML = `
`;
+ }
+ anzhiyu.changeMusicBg(false);
+ },
+ //隐藏今日推荐
+ hideTodayCard: function () {
+ if (document.getElementById("todayCard")) {
+ document.getElementById("todayCard").classList.add("hide");
+ const topGroup = document.querySelector(".topGroup");
+ const recentPostItems = topGroup.querySelectorAll(".recent-post-item");
+ recentPostItems.forEach(item => {
+ item.style.display = "flex";
+ });
+ }
+ },
+
+ // 监听音乐背景改变
+ addEventListenerMusic: function () {
+ const anMusicPage = document.getElementById("anMusic-page");
+ const aplayerIconMenu = anMusicPage.querySelector(".aplayer-info .aplayer-time .aplayer-icon-menu");
+ const anMusicBtnGetSong = anMusicPage.querySelector("#anMusicBtnGetSong");
+ const anMusicRefreshBtn = anMusicPage.querySelector("#anMusicRefreshBtn");
+ const anMusicSwitchingBtn = anMusicPage.querySelector("#anMusicSwitching");
+ const metingAplayer = anMusicPage.querySelector("meting-js").aplayer;
+ //初始化音量
+ metingAplayer.volume(0.8, true);
+ metingAplayer.on("loadeddata", function () {
+ anzhiyu.changeMusicBg();
+ });
+
+ aplayerIconMenu.addEventListener("click", function () {
+ document.getElementById("menu-mask").style.display = "block";
+ document.getElementById("menu-mask").style.animation = "0.5s ease 0s 1 normal none running to_show";
+ anMusicPage.querySelector(".aplayer.aplayer-withlist .aplayer-list").style.opacity = "1";
+ });
+
+ function anMusicPageMenuAask() {
+ if (window.location.pathname != "/music/") {
+ document.getElementById("menu-mask").removeEventListener("click", anMusicPageMenuAask);
+ return;
+ }
+
+ anMusicPage.querySelector(".aplayer-list").classList.remove("aplayer-list-hide");
+ }
+
+ document.getElementById("menu-mask").addEventListener("click", anMusicPageMenuAask);
+
+ // 监听增加单曲按钮
+ anMusicBtnGetSong.addEventListener("click", () => {
+ if (changeMusicListFlag) {
+ const anMusicPage = document.getElementById("anMusic-page");
+ const metingAplayer = anMusicPage.querySelector("meting-js").aplayer;
+ const allAudios = metingAplayer.list.audios;
+ const randomIndex = Math.floor(Math.random() * allAudios.length);
+ // 随机播放一首
+ metingAplayer.list.switch(randomIndex);
+ } else {
+ anzhiyu.cacheAndPlayMusic();
+ }
+ });
+ anMusicRefreshBtn.addEventListener("click", () => {
+ localStorage.removeItem("musicData");
+ anzhiyu.snackbarShow("已移除相关缓存歌曲");
+ });
+ anMusicSwitchingBtn.addEventListener("click", () => {
+ anzhiyu.changeMusicList();
+ });
+
+ // 监听键盘事件
+ //空格控制音乐
+ document.addEventListener("keydown", function (event) {
+ //暂停开启音乐
+ if (event.code === "Space") {
+ event.preventDefault();
+ metingAplayer.toggle();
+ }
+ //切换下一曲
+ if (event.keyCode === 39) {
+ event.preventDefault();
+ metingAplayer.skipForward();
+ }
+ //切换上一曲
+ if (event.keyCode === 37) {
+ event.preventDefault();
+ metingAplayer.skipBack();
+ }
+ //增加音量
+ if (event.keyCode === 38) {
+ if (musicVolume <= 1) {
+ musicVolume += 0.1;
+ metingAplayer.volume(musicVolume, true);
+ }
+ }
+ //减小音量
+ if (event.keyCode === 40) {
+ if (musicVolume >= 0) {
+ musicVolume += -0.1;
+ metingAplayer.volume(musicVolume, true);
+ }
+ }
+ });
+ },
+ // 切换歌单
+ changeMusicList: async function () {
+ const anMusicPage = document.getElementById("anMusic-page");
+ const metingAplayer = anMusicPage.querySelector("meting-js").aplayer;
+ const currentTime = new Date().getTime();
+ const cacheData = JSON.parse(localStorage.getItem("musicData")) || { timestamp: 0 };
+ let songs = [];
+
+ if (changeMusicListFlag) {
+ songs = defaultPlayMusicList;
+ } else {
+ // 保存当前默认播放列表,以使下次可以切换回来
+ defaultPlayMusicList = metingAplayer.list.audios;
+ // 如果缓存的数据没有过期,直接使用
+ if (currentTime - cacheData.timestamp < 24 * 60 * 60 * 1000) {
+ songs = cacheData.songs;
+ } else {
+ // 否则重新从服务器获取数据
+ const response = await fetch("/json/music.json");
+ songs = await response.json();
+ cacheData.timestamp = currentTime;
+ cacheData.songs = songs;
+ localStorage.setItem("musicData", JSON.stringify(cacheData));
+ }
+ }
+
+ // 清除当前播放列表并添加新的歌曲
+ metingAplayer.list.clear();
+ metingAplayer.list.add(songs);
+
+ // 切换标志位
+ changeMusicListFlag = !changeMusicListFlag;
+ },
+ // 控制台音乐列表监听
+ addEventListenerConsoleMusicList: function () {
+ const navMusic = document.getElementById("nav-music");
+ if (!navMusic) return;
+ navMusic.addEventListener("click", e => {
+ const aplayerList = navMusic.querySelector(".aplayer-list");
+ const listBtn = navMusic.querySelector(
+ "div.aplayer-info > div.aplayer-controller > div.aplayer-time.aplayer-time-narrow > button.aplayer-icon.aplayer-icon-menu svg"
+ );
+ if (e.target != listBtn && aplayerList.classList.contains("aplayer-list-hide")) {
+ aplayerList.classList.remove("aplayer-list-hide");
+ }
+ });
+ },
+ // 监听按键
+ toPage: function () {
+ var toPageText = document.getElementById("toPageText"),
+ toPageButton = document.getElementById("toPageButton"),
+ pageNumbers = document.querySelectorAll(".page-number"),
+ lastPageNumber = Number(pageNumbers[pageNumbers.length - 1].innerHTML),
+ pageNumber = Number(toPageText.value);
+
+ if (!isNaN(pageNumber) && pageNumber >= 1 && Number.isInteger(pageNumber)) {
+ var url = "/page/" + (pageNumber > lastPageNumber ? lastPageNumber : pageNumber) + "/";
+ toPageButton.href = pageNumber === 1 ? "/" : url;
+ } else {
+ toPageButton.href = "javascript:void(0);";
+ }
+ },
+
+ //删除多余的class
+ removeBodyPaceClass: function () {
+ document.body.className = "pace-done";
+ },
+ // 修改body的type类型以适配css
+ setValueToBodyType: function () {
+ const input = document.getElementById("page-type"); // 获取input元素
+ const value = input.value; // 获取input的value值
+ document.body.dataset.type = value; // 将value值赋值到body的type属性上
+ },
+ //匿名评论
+ addRandomCommentInfo: function () {
+ // 从形容词数组中随机取一个值
+ const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)];
+
+ // 从蔬菜水果动物名字数组中随机取一个值
+ const randomName = vegetablesAndFruits[Math.floor(Math.random() * vegetablesAndFruits.length)];
+
+ // 将两个值组合成一个字符串
+ const name = `${randomAdjective}${randomName}`;
+
+ function dr_js_autofill_commentinfos() {
+ var lauthor = [
+ "#author",
+ "input[name='comname']",
+ "#inpName",
+ "input[name='author']",
+ "#ds-dialog-name",
+ "#name",
+ "input[name='nick']",
+ "#comment_author",
+ ],
+ lmail = [
+ "#mail",
+ "#email",
+ "input[name='commail']",
+ "#inpEmail",
+ "input[name='email']",
+ "#ds-dialog-email",
+ "input[name='mail']",
+ "#comment_email",
+ ],
+ lurl = [
+ "#url",
+ "input[name='comurl']",
+ "#inpHomePage",
+ "#ds-dialog-url",
+ "input[name='url']",
+ "input[name='website']",
+ "#website",
+ "input[name='link']",
+ "#comment_url",
+ ];
+ for (var i = 0; i < lauthor.length; i++) {
+ var author = document.querySelector(lauthor[i]);
+ if (author != null) {
+ author.value = name;
+ author.dispatchEvent(new Event("input"));
+ author.dispatchEvent(new Event("change"));
+ break;
+ }
+ }
+ for (var j = 0; j < lmail.length; j++) {
+ var mail = document.querySelector(lmail[j]);
+ if (mail != null) {
+ mail.value = visitorMail;
+ mail.dispatchEvent(new Event("input"));
+ mail.dispatchEvent(new Event("change"));
+ break;
+ }
+ }
+ return !1;
+ }
+
+ dr_js_autofill_commentinfos();
+ var input = document.getElementsByClassName("el-textarea__inner")[0];
+ input.focus();
+ input.setSelectionRange(-1, -1);
+ },
+
+ // 跳转开往
+ totraveling: function () {
+ anzhiyu.snackbarShow(
+ "即将跳转到「开往」项目的成员博客,不保证跳转网站的安全性和可用性",
+ element => {
+ element.style.opacity = 0;
+ travellingsTimer && clearTimeout(travellingsTimer);
+ },
+ 5000,
+ "取消"
+ );
+ travellingsTimer = setTimeout(function () {
+ window.open("https://www.travellings.cn/go.html", "_blank");
+ }, "5000");
+ },
+
+ // 工具函数替换字符串
+ replaceAll: function (e, n, t) {
+ return e.split(n).join(t);
+ },
+
+ // 音乐绑定事件
+ musicBindEvent: function () {
+ document.querySelector("#nav-music .aplayer-music").addEventListener("click", function () {
+ anzhiyu.musicTelescopic();
+ });
+ document.querySelector("#nav-music .aplayer-button").addEventListener("click", function () {
+ anzhiyu.musicToggle(false);
+ });
+ },
+
+ // 判断是否是移动端
+ hasMobile: function () {
+ let isMobile = false;
+ if (
+ navigator.userAgent.match(
+ /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
+ ) ||
+ document.body.clientWidth < 800
+ ) {
+ // 移动端
+ isMobile = true;
+ }
+ return isMobile;
+ },
+
+ // 创建二维码
+ qrcodeCreate: function () {
+ if (document.getElementById("qrcode")) {
+ document.getElementById("qrcode").innerHTML = "";
+ var qrcode = new QRCode(document.getElementById("qrcode"), {
+ text: window.location.href,
+ width: 250,
+ height: 250,
+ colorDark: "#000",
+ colorLight: "#ffffff",
+ correctLevel: QRCode.CorrectLevel.H,
+ });
+ }
+ },
+
+ // 判断是否在el内
+ isInViewPortOfOne: function (el) {
+ if (!el) return;
+ const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
+ const offsetTop = el.offsetTop;
+ const scrollTop = document.documentElement.scrollTop;
+ const top = offsetTop - scrollTop;
+ return top <= viewPortHeight;
+ },
+ //添加赞赏蒙版
+ addRewardMask: function () {
+ if (!document.querySelector(".reward-main")) return;
+ document.querySelector(".reward-main").style.display = "flex";
+ document.querySelector(".reward-main").style.zIndex = "102";
+ document.getElementById("quit-box").style.display = "flex";
+ },
+ // 移除赞赏蒙版
+ removeRewardMask: function () {
+ if (!document.querySelector(".reward-main")) return;
+ document.querySelector(".reward-main").style.display = "none";
+ document.getElementById("quit-box").style.display = "none";
+ },
+
+ keyboardToggle: function () {
+ const isKeyboardOn = anzhiyu_keyboard;
+
+ if (isKeyboardOn) {
+ const consoleKeyboard = document.querySelector("#consoleKeyboard");
+ consoleKeyboard.classList.remove("on");
+ anzhiyu_keyboard = false;
+ } else {
+ const consoleKeyboard = document.querySelector("#consoleKeyboard");
+ consoleKeyboard.classList.add("on");
+ anzhiyu_keyboard = true;
+ }
+
+ localStorage.setItem("keyboardToggle", isKeyboardOn ? "false" : "true");
+ },
+ rightMenuToggle: function () {
+ if (window.oncontextmenu) {
+ window.oncontextmenu = null;
+ } else if (!window.oncontextmenu && oncontextmenuFunction) {
+ window.oncontextmenu = oncontextmenuFunction;
+ }
+ },
+ switchConsole: () => {
+ // switch console
+ const consoleEl = document.getElementById("console");
+ //初始化隐藏边栏
+ const $htmlDom = document.documentElement.classList;
+ $htmlDom.contains("hide-aside")
+ ? document.querySelector("#consoleHideAside").classList.add("on")
+ : document.querySelector("#consoleHideAside").classList.remove("on");
+ if (consoleEl.classList.contains("show")) {
+ consoleEl.classList.remove("show");
+ } else {
+ consoleEl.classList.add("show");
+ }
+ const consoleKeyboard = document.querySelector("#consoleKeyboard");
+
+ if (consoleKeyboard) {
+ if (localStorage.getItem("keyboardToggle") === "true") {
+ consoleKeyboard.classList.add("on");
+ anzhiyu_keyboard = true;
+ } else {
+ consoleKeyboard.classList.remove("on");
+ anzhiyu_keyboard = false;
+ }
+ }
+ },
+ // 定义 intersectionObserver 函数,并接收两个可选参数
+ intersectionObserver: function (enterCallback, leaveCallback) {
+ let observer;
+ return () => {
+ if (!observer) {
+ observer = new IntersectionObserver(entries => {
+ entries.forEach(entry => {
+ if (entry.intersectionRatio > 0) {
+ enterCallback?.();
+ } else {
+ leaveCallback?.();
+ }
+ });
+ });
+ } else {
+ // 如果 observer 对象已经存在,则先取消对之前元素的观察
+ observer.disconnect();
+ }
+ return observer;
+ };
+ },
+ // CategoryBar滚动
+ scrollCategoryBarToRight: function () {
+ // 获取需要操作的元素
+ const items = document.getElementById("catalog-list");
+ const nextButton = document.getElementById("category-bar-next");
+
+ // 检查元素是否存在
+ if (items && nextButton) {
+ const itemsWidth = items.clientWidth;
+
+ // 判断是否已经滚动到最右侧
+ if (items.scrollLeft + items.clientWidth + 1 >= items.scrollWidth) {
+ // 滚动到初始位置并更新按钮内容
+ items.scroll({
+ left: 0,
+ behavior: "smooth",
+ });
+ nextButton.innerHTML = '
';
+ } else {
+ // 滚动到下一个视图
+ items.scrollBy({
+ left: itemsWidth,
+ behavior: "smooth",
+ });
+ }
+ } else {
+ console.error("Element(s) not found: 'catalog-list' and/or 'category-bar-next'.");
+ }
+ },
+ // 分类条
+ categoriesBarActive: function () {
+ const urlinfo = decodeURIComponent(window.location.pathname);
+ const $categoryBar = document.getElementById("category-bar");
+ if (!$categoryBar) return;
+
+ if (urlinfo === "/") {
+ $categoryBar.querySelector("#首页").classList.add("select");
+ } else {
+ const pattern = /\/categories\/.*?\//;
+ const patbool = pattern.test(urlinfo);
+ if (!patbool) return;
+
+ const nowCategorie = urlinfo.split("/")[2];
+ $categoryBar.querySelector(`#${nowCategorie}`).classList.add("select");
+ }
+ },
+ topCategoriesBarScroll: function () {
+ const $categoryBarItems = document.getElementById("category-bar-items");
+ if (!$categoryBarItems) return;
+
+ $categoryBarItems.addEventListener("mousewheel", function (e) {
+ const v = -e.wheelDelta / 2;
+ this.scrollLeft += v;
+ e.preventDefault();
+ });
+ },
+ // 切换菜单显示热评
+ switchRightClickMenuHotReview: function () {
+ const postComment = document.getElementById("post-comment");
+ const menuCommentBarrageDom = document.getElementById("menu-commentBarrage");
+ if (postComment) {
+ menuCommentBarrageDom.style.display = "flex";
+ } else {
+ menuCommentBarrageDom.style.display = "none";
+ }
+ },
+ // 切换作者卡片状态文字
+ changeSayHelloText: function () {
+ const greetings = GLOBAL_CONFIG.authorStatus.skills;
+
+ const authorInfoSayHiElement = document.getElementById("author-info__sayhi");
+
+ // 如果只有一个问候语,设置为默认值
+ if (greetings.length === 1) {
+ authorInfoSayHiElement.textContent = greetings[0];
+ return;
+ }
+
+ let lastSayHello = authorInfoSayHiElement.textContent;
+
+ let randomGreeting = lastSayHello;
+ while (randomGreeting === lastSayHello) {
+ randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
+ }
+ authorInfoSayHiElement.textContent = randomGreeting;
+ },
+};
+
+const anzhiyuPopupManager = {
+ queue: [],
+ processing: false,
+ Jump: false,
+
+ enqueuePopup(title, tip, url, duration = 3000) {
+ this.queue.push({ title, tip, url, duration });
+ if (!this.processing) {
+ this.processQueue();
+ }
+ },
+
+ processQueue() {
+ if (this.queue.length > 0 && !this.processing) {
+ this.processing = true;
+ const { title, tip, url, duration } = this.queue.shift();
+ this.popupShow(title, tip, url, duration);
+ }
+ },
+
+ popupShow(title, tip, url, duration) {
+ const popupWindow = document.getElementById("popup-window");
+ if (!popupWindow) return;
+ const windowTitle = popupWindow.querySelector(".popup-window-title");
+ const windowContent = popupWindow.querySelector(".popup-window-content");
+ const cookiesTip = windowContent.querySelector(".popup-tip");
+ if (popupWindow.classList.contains("show-popup-window")) {
+ popupWindow.classList.add("popup-hide");
+ }
+
+ // 等待上一个弹窗完全消失
+ setTimeout(() => {
+ // 移除之前的点击事件处理程序
+ popupWindow.removeEventListener("click", this.clickEventHandler);
+ if (url) {
+ if (window.pjax) {
+ this.clickEventHandler = event => {
+ event.preventDefault();
+ pjax.loadUrl(url);
+ popupWindow.classList.remove("show-popup-window");
+ popupWindow.classList.remove("popup-hide");
+ this.Jump = true;
+
+ // 处理队列中的下一个弹出窗口
+ this.processing = false;
+ this.processQueue();
+ };
+
+ popupWindow.addEventListener("click", this.clickEventHandler);
+ } else {
+ this.clickEventHandler = () => {
+ window.location.href = url;
+ };
+ popupWindow.addEventListener("click", this.clickEventHandler);
+ }
+ if (popupWindow.classList.contains("no-url")) {
+ popupWindow.classList.remove("no-url");
+ }
+ } else {
+ if (!popupWindow.classList.contains("no-url")) {
+ popupWindow.classList.add("no-url");
+ }
+
+ this.clickEventHandler = () => {
+ popupWindow.classList.add("popup-hide");
+ setTimeout(() => {
+ popupWindow.classList.remove("popup-hide");
+ popupWindow.classList.remove("show-popup-window");
+ }, 1000);
+ };
+ popupWindow.addEventListener("click", this.clickEventHandler);
+ }
+
+ if (popupWindow.classList.contains("popup-hide")) {
+ popupWindow.classList.remove("popup-hide");
+ }
+ popupWindow.classList.add("show-popup-window");
+ windowTitle.textContent = title;
+ cookiesTip.textContent = tip;
+ }, 800);
+
+ setTimeout(() => {
+ if (url && !this.Jump) {
+ this.Jump = false;
+ }
+ if (!popupWindow.classList.contains("popup-hide") && popupWindow.className != "") {
+ popupWindow.classList.add("popup-hide");
+ }
+
+ // 处理队列中的下一个弹出窗口
+ this.processing = false;
+ this.processQueue();
+ }, duration);
+ },
+};